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'
package main
import "fmt"
func printTypeAndValue(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
}
}
func panicOnInvalidConversion() {
var iv interface{} = "string"
v := iv.(int)
fmt.Printf("v is int of value: %d\n", v)
}
func main() {
// pass a string
printTypeAndValue("string")
i := 5
// pass an int
printTypeAndValue(i)
// pass a pointer to int i.e. *int
printTypeAndValue(&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))。这又称为类型断言。
func panicOnInvalidConversion(iv interface{}) {
v := iv.(int)
fmt.Printf("v is int of value: %d\n", v)
}
func main() {
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.
package main
import (
"fmt"
"strconv"
)
func smartConvertToInt(iv interface{}) (int, error) {
// inside case statements, v is of type matching case type
switch v := iv.(type) {
case int:
return v, nil
case string:
return strconv.Atoi(v)
case float64:
return int(v), nil
default:
return 0, fmt.Errorf("unsupported type: %T", iv)
}
}
func printSmartConvertToInt(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)
}
func main() {
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.