I often have a situation, where I expect an int
(of any type, int/int8/16/32/64
) and check for it using a type switch
switch t := v.(type) {
case int, int8, int16, int32, int64:
// cast to int64
case uint, uint8, uint16, uint32, uint64:
// cast to uint64
}
Now I cannot use a direct cast, because t
in this case will be of type interface{}
. Do I really have to split this up into case
s for each integer type?
I know that I could do it via reflection using reflect.ValueOf(v).Int()
, but shouldn't there be a better (less verbose) way of doing this?
UPDATE:
Filed an issue, and Rob advised to just use reflect
in this case.
You can use the strconv package's Atoi() function to convert the string into an integer value. Atoi stands for ASCII to integer. The Atoi() function returns two values: the result of the conversion, and the error (if any).
int64 is a version of int that only stores signed numeric values composed of up to 64 bits. So, for example, if you try to store a string value in it, or an integer beyond what can be made using 64 bits, the program would return an error or result in an integer overflow.
You can convert numbers to strings by using the strconv. Itoa method from the strconv package in the Go standard libary. If you pass either a number or a variable into the parentheses of the method, that numeric value will be converted into a string value.
It's hard to give you an opinion without more context but it looks like you're trying to make your implementation too generic, which is common from people that worked mostly with more dynamic languages or w/ generic support.
Part of the process of Learning Go is learning to embrace its type system, and depending on where you're coming from, it can be challenging.
Usually, in Go, you want to support one type that can hold all possible values you need to handle. In your case it would probably be a int64.
Take a look on the math package, for example. It only work with int64 and expect anyone using it to typecast it properly instead of trying to convert everything.
Another option is to use a interface to be type-agnostic, like the sort package does. Basically, any method that are type specific will be implemented outside of your package and you expect certain methods to be defined.
It takes a while to learn and accept these attributes but overall, in the end, it proves to be good in terms of maintainability and robustness. Interfaces ensure you have orthogonality and strong types makes sure you're in control of type conversions, which in the end can cause bugs and also unnecessary copies in memory.
Cheers
What problem are you trying to solve? The full solution that you've described looks like this:
func Num64(n interface{}) interface{} {
switch n := n.(type) {
case int:
return int64(n)
case int8:
return int64(n)
case int16:
return int64(n)
case int32:
return int64(n)
case int64:
return int64(n)
case uint:
return uint64(n)
case uintptr:
return uint64(n)
case uint8:
return uint64(n)
case uint16:
return uint64(n)
case uint32:
return uint64(n)
case uint64:
return uint64(n)
}
return nil
}
func DoNum64Things(x interface{}) {
switch Num64(x).(type) {
case int64:
// do int things
case uint64:
// do uint things
default:
// do other things
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With