系列文章:
golang利用组合实现继承,和php或java面向对象的继承有何不同
所谓 类型断言(type assertion):
cannot convert a (type interface{}) to type string: need type assertion
直接转换
如果明确知道a的类型,可以直接转换:
package main import "fmt" func main() { var i interface{} i = "cuishuang" f(i) } func f(a interface{}) string { fmt.Println(a) return a.(string) }
则编译通过.
格式为 a.(对应的类型)
但如果"()"里面的类型不对,则会直接panic
package main import "fmt" func main() { var i interface{} i = "cuishuang" f(i) } func f(a interface{}) string { fmt.Println(a.(int)) return "" }
输出为:
panic: interface conversion: interface {} is string, not int goroutine 1 [running]:
OK判别式
如上,如果类型不一致,会直接panic。所以一般在断言时,都要用OK判别式的格式(哪怕只是value, _ := a.(float32)
,起码这样不会panic了)
如:
package main import "fmt" func main() { var i interface{} i = "cuishuang" f(i) } func f(a interface{}) string { value, _ := a.(float32) fmt.Println("value ", value) return "" }
输出为:value 0
而如果:
package main import "fmt" func main() { var i interface{} i = "cuishuang" f(i) } func f(a interface{}) string { value := a.(float32) fmt.Println("value ", value) return "" }
则会
panic: interface conversion: interface {} is string, not float32 goroutine 1 [running]: main.f({0x10071baa0?, 0x10072c748?}) /Users/fliter/go/src/shuang/interfacee/assert.go:13 +0xb4 main.main() /Users/fliter/go/src/shuang/interfacee/assert.go:8 +0x2c exit status 2
golangci-lint有一个检查项 forcetypeassert,用来强制类型断言,检查interface转换有没有进行类型校验
在断言时进行判断:
- 如果断言失败,那么ok的值将会是false.
- 如果断言成功, ok的值将会是true, 同时value就是所期待的正确的值
package main import "fmt" func main() { var i interface{} i = "cuishuang" f(i) } func f(a interface{}) string { value,ok := a.(int) if ok { fmt.Println(a.(int)) //a.(int) 即 value fmt.Println(value) } else { fmt.Println("i中不是int类型") } return "" }
输出为:
i中不是int类型
配合switch语句进行判断
package main import "fmt" func main() { var i interface{} i = "cuishuang" f(i) } func f(a interface{}) string { switch val := a.(type) { default: fmt.Printf("unexpected type %T", val) // %T prints whatever type t has break case bool: fmt.Printf("boolean: %t\n", val) // t has type bool break case int: fmt.Printf("integer: %d\n", val) // t has type int break case string: fmt.Printf("string: %s\n", val) // t has type string break case *bool: fmt.Printf("pointer to boolean: %t\n", *val) // t has type *bool break case *int: fmt.Printf("pointer to integer: %d\n", *val) // t has type *int case *string: fmt.Printf("pointer to string: %s\n", *val) // t has type *string break } return "" }
输出为:
string: cuishuang
参考: