How can I convert custom type to interface{}
and then to base type (ex. uint8
)?
I can't use direct cast like uint16(val.(Year))
because I may not know all custom types, but I can determinate base types (uint8
, uint32
,...) in runtime
There are many custom types (usually used as enums) based on numeric:
ex:
type Year uint16
type Day uint8
type Month uint8
and so on...
The question is about type casting from interface{}
to base types:
package main
import "fmt"
type Year uint16
// ....
//Many others custom types based on uint8
func AsUint16(val interface{}) uint16 {
return val.(uint16) //FAIL: cannot convert val (type interface {}) to type uint16: need type assertion
}
func AsUint16_2(val interface{}) uint16 {
return uint16(val) //FAIL: cannot convert val (type interface {}) to type uint16: need type assertion
}
func main() {
fmt.Println(AsUint16_2(Year(2015)))
}
You can accomplish this by using the reflect
package:
package main
import "fmt"
import "reflect"
type Year uint16
func AsUint16(val interface{}) uint16 {
ref := reflect.ValueOf(val)
if ref.Kind() != reflect.Uint16 {
return 0
}
return uint16(ref.Uint())
}
func main() {
fmt.Println(AsUint16(Year(2015)))
}
Depending on your situation, you may want to return (uint16, error)
, instead of returning the empty value.
Why did you include Year
in the question? Are you hoping to convert arbitrary things into Years, or convert Years into uint16s?
If I assume you meant the latter case, then it would be better to use a method
func (y Year) AsUint16() uint16 {
return uint16(y)
}
which doesn't need any type assertions or reflection.