packagemainimport"fmt"funcprintVariableType(v interface{}) {switch v.(type) {casestring: fmt.Printf("v is of type 'string'\n")caseint: fmt.Printf("v is of type 'int'\n")default:// generic fallback fmt.Printf("v is of type '%T'\n", v) }}funcmain() {printVariableType("string") // stringprintVariableType(5) // intprintVariableType(int32(5)) // int32}
v is of type 'string'
v is of type 'int'
v is of type 'int32'
在编译时,如果您拿到了接口(包括空接口)类型的数据,那您并不知道它真实的、底层的数据类型。
但您可以在运行时,通过类型断言获取其底层类型。
packagemainimport"fmt"funcprintTypeAndValue(iv interface{}) {if v, ok := iv.(string); ok { fmt.Printf("iv is of type string and has value '%s'\n", v)return }if v, ok := iv.(int); ok { fmt.Printf("iv is of type int and has value '%d'\n", v)return }if v, ok := iv.(*int); ok { fmt.Printf("iv is of type *int and has value '%p'\n", v)return }}funcpanicOnInvalidConversion() {var iv interface{} ="string" v := iv.(int) fmt.Printf("v is int of value: %d\n", v)}funcmain() {// pass a stringprintTypeAndValue("string") i :=5// pass an intprintTypeAndValue(i)// pass a pointer to int i.e. *intprintTypeAndValue(&i)panicOnInvalidConversion()}
iv is of type string and has value 'string'
iv is of type int and has value '5'
iv is of type *int and has value '0xc00002c008'
panic: interface conversion: interface {} is string, not int
goroutine 1 [running]:
main.panicOnInvalidConversion()
/tmp/sandbox390319121/prog.go:23 +0x45
main.main()
/tmp/sandbox390319121/prog.go:36 +0x9a
Program exited: status 2.
类型断言(Type assertion)
类型断言使得您能够检查空接口的值是否是某个给定的类型。
为了语法的完整性,类型交换机(type switch)有简短版本:v := iv.(int)(或者v, ok := iv.(int))。这又称为类型断言。
funcpanicOnInvalidConversion(iv interface{}) { v := iv.(int) fmt.Printf("v is int of value: %d\n", v)}funcmain() {panicOnInvalidConversion("string")}
panic: interface conversion: interface {} is string, not int
goroutine 1 [running]:
main.panicOnInvalidConversion(0x4a0b40, 0x4dae60)
/tmp/sandbox387618651/prog.go:6 +0xd6
main.main()
/tmp/sandbox387618651/prog.go:11 +0x39
Program exited: status 2.
packagemainimport ("fmt""strconv")funcsmartConvertToInt(iv interface{}) (int, error) {// inside case statements, v is of type matching case typeswitch v := iv.(type) {caseint:return v, nilcasestring:return strconv.Atoi(v)casefloat64:returnint(v), nildefault:return0, fmt.Errorf("unsupported type: %T", iv) }}funcprintSmartConvertToInt(iv interface{}) { i, err :=smartConvertToInt(iv)if err !=nil { fmt.Printf("Failed to convert %#v to int\n", iv)return } fmt.Printf("%#v of type %T converted to %d\n", iv, iv, i)}funcmain() {printSmartConvertToInt("5")printSmartConvertToInt(4)printSmartConvertToInt(int32(8))printSmartConvertToInt("not valid int")}
"5" of type string converted to 5
4 of type int converted to 4
Failed to convert 8 to int
Failed to convert "not valid int" to int
Program exited.