A
A
Alexey Sumin2019-12-25 16:49:01
go
Alexey Sumin, 2019-12-25 16:49:01

Type casting in GO, can be made prettier?

We need a function that:
- accepts anything at the input
- at the output, if possible, a number of type int64 should be returned
The result is the following code:

func interToInt64(inp interface{}) (int64, error) {
  switch inp.(type) {
  case int:
    return int64(inp.(int)), nil
  case int8:
    return int64(inp.(int8)), nil
  case int16:
    return int64(inp.(int16)), nil
  case int32:
    return int64(inp.(int32)), nil
  case int64:
    return inp.(int64), nil
  case uint:
    return int64(inp.(uint)), nil
  case uint8:
    return int64(inp.(uint8)), nil
  case uint16:
    return int64(inp.(uint16)), nil
  case uint32:
    return int64(inp.(uint32)), nil
  case uint64:
    return int64(inp.(uint64)), nil
  case string:
    return strconv.ParseInt(inp.(string), 10, 64)
  default:
    return 0, fmt.Errorf("unsupported type %T", inp)
  }
}

Is it possible to solve this problem in a more accurate way? It's annoying that you have to explicitly enumerate all possible subtypes of ints.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexander Pavlyuk, 2019-12-25
@asumin

You can do this, there will be less code. For the rest, nothing can be reduced, because go is a rather low-level language.

func interToInt64(inp interface{}) (int64, error) {
  switch v := inp.(type) {
  case int:
    return int64(v), nil
  case int8:
    return int64(v), nil
  case int16:
    return int64(v), nil
  case int32:
    return int64(v), nil
  case int64:
    return v, nil
  case uint:
    return int64(v), nil
  case uint8:
    return int64(v), nil
  case uint16:
    return int64(v), nil
  case uint32:
    return int64(v), nil
  case uint64:
    return int64(v), nil
  case string:
    return strconv.ParseInt(v, 10, 64)
  default:
    return 0, fmt.Errorf("unsupported type %T", inp)
  }
}

P
Philipp, 2019-12-26
@zoonman

The idea of ​​such a function is not the most sensible. Conversion of some numbers will cause unpredictable behavior.
Something along the lines of uint64(2^32+1) can really shake your int64.
I advise you not to play with fire and consider alternative ways of working with data.

D
devalone, 2019-12-25
@devalone

Another option:

package main

import (
  "fmt"
  "strconv"
)

func main() {
  fmt.Println(interToInt64(1))
  fmt.Println(interToInt64(int64(10)))
  fmt.Println(interToInt64(int8(10)))
  fmt.Println(interToInt64(15.5))
  fmt.Println(interToInt64("15.5"))
  fmt.Println(interToInt64("15"))
  fmt.Println(interToInt64(uint(10)))
  fmt.Println(interToInt64(uint64(999)))
  fmt.Println(interToInt64(uint64(18446744073709551615)))
}

func interToInt64(inp interface{}) (int64, error) {
  strVal := fmt.Sprint(inp)
  if res, err := strconv.ParseInt(strVal, 10, 64); err == nil {
    return res, nil
  }
  return 0, fmt.Errorf("unsupported type %T with value %v", inp, inp)
}

https://play.golang.org/p/Q0_5UIoU3KP

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question