将类型转换为基本类型

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

http://play.golang.org/p/cyAnzQ90At

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.

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

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.

https://play.golang.org/p/9wCQJe46PU