Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go: cast any int value to int64 in type switch

Tags:

casting

go

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 cases 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.

like image 200
Era Avatar asked Jun 20 '13 18:06

Era


People also ask

How do you cast to int in go?

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).

What is int64 Golang?

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.

How to convert any value to string in Golang?

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.


2 Answers

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

like image 129
Rodrigo Kochenburger Avatar answered Sep 24 '22 03:09

Rodrigo Kochenburger


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
    }
}
like image 30
peterSO Avatar answered Sep 24 '22 03:09

peterSO