Reputation: 253
I have a variable which value can be string or int depend on the input. I use interface{}
as the type. How to convert the value of that variable to int
if the input is like "50"
, "45"
, or any string of int.
package main
import "fmt"
import "log"
import "strconv"
func main() {
var limit interface{}
limit = "50"
page := 1
offset := 0
if limit != "ALL" {
log.Println("INSIDE")
offset = limit.(int)*page - limit.(int)
}
fmt.Println(offset)
}
Above code got:
interface conversion: interface {} is string, not int
If I use this:
package main
import "fmt"
import "log"
import "strconv"
func main() {
var limit interface{}
limit = "50"
page := 1
offset := 0
if limit != "ALL" {
log.Println("INSIDE")
offset = strconv.Atoi(limit)*page - strconv.Atoi(limit)
}
fmt.Println(offset)
}
I got this
exit status 2
command-line-arguments
./main.go:14:24: cannot use limit (type interface {}) as type string in argument to strconv.Atoi: need type assertion
./main.go:14:24: multiple-value strconv.Atoi() in single-value context
./main.go:14:51: cannot use limit (type interface {}) as type string in argument to strconv.Atoi: need type assertion
./main.go:14:51: multiple-value strconv.Atoi() in single-value context
How to convert value of that variable to int?
Upvotes: 1
Views: 5922
Reputation: 8706
In Go, in contrast to languages such as Python/JavaScript/Perl, the variables have strict types and strong boundaries. You have to write explicit code to make the conversion of a string from/to an integer. This is helpful to write safer and more performant programs.
In addition, if the variable is stored in an interface{}
you have to use a type assertion (or a type switch) to further use the content with a specific type.
Here is your fixed code:
package main
import "fmt"
import "log"
import "strconv"
func main() {
var limit interface{}
limit = "50"
page := 1
offset := 3
if limit != "ALL" {
// Type assertion
s, isString := limit.(string)
if !isString {
log.Fatalf("limit is not a string but %T", limit)
}
// Conversion from string to int, with error handling
l, err := strconv.Atoi(s)
if err != nil {
log.Fatalf("%s: %v", limit, err)
}
offset = l*page - l
}
fmt.Println(offset)
}
However, I suggest that you just use the string
type for the limit variable.
Upvotes: 1
Reputation: 685
As I understood your question, value of your limit
in fact is always string, but in one case it's value == ALL
, otherwise it's a string representation of an integer value.
If I'm right, then I would provide following solution:
import (
"errors"
"fmt"
"strconv"
)
func getOffset(limit string, page int64) (int64, error) {
lim, err := strconv.ParseInt(limit, 10, 64)
if err != nil {
if limit == "ALL" {
return 0, nil
}
return 0, errors.New(fmt.Sprintf("string '%v' doesn't fit requirements, error: %v", limit, err))
}
offset := lim*page - lim
return offset, nil
}
Full solution on playground: https://play.golang.org/p/fJv9_cw18R5
Upvotes: 0
Reputation: 2891
package main
import (
"fmt"
"strconv"
)
func main() {
var lim interface{}
lim = "10"
fmt.Printf("Type is: %T\nValue is: %s \n", lim, lim.(string))
i, _ := strconv.Atoi(lim.(string))
fmt.Printf("After conversion value is: %d", i)
}
Output of the above code:
Type is: string, Value is: 10 After conversion value is: 10
Upvotes: 0