1. 空接口既然能够存储任意类型的值,那么从空接口获取到的值是否能够间接应用?看上面栗子
package mainimport ( "fmt")var a interface{}var b interface{}func main() { a = 1024 b = 100 res := a + b fmt.Println(res)}

报错:

invalid operation: operator + not defined on a (variable of type interface{}) (exit status 2)
程序报错的起因:因为空接口的类型是不能够间接应用的,须要正告类型断言转换方可应用。
  1. 这次咱们应用类型断言来将接口类型转成int类型
package mainimport ( "fmt")var a interface{}var b interface{}func main() { a = 1024 b = 100 val1, res1 := a.(int) fmt.Println(val1, res1) val2, res2 := b.(int) fmt.Println(val2, res2) //val1和val2接管转换后的值,res1和res2是类型断言的状态(胜利或失败),断言胜利是true,反之false}

输入:

1024 true100 true
  1. 类型断言新姿态:当应用一个值承受断言后果时,则会间接返回断言后的值
package mainimport ( "fmt")var a interface{}var b interface{}func main() { a = 1024 b = 100    //类型断言转换 a1 := a.(int) b1 := b.(int)    //转换后进行相加,就不会报错了 res := a1 + b1 fmt.Println(res)}
  1. 领会一下应用类型断言转换失败的快感
package mainimport ( "fmt" "log")var a interface{}func main() { a = 1024 if a1, r := a.(string); r {  fmt.Println(a1) } else {  log.Fatalln("类型断言转换失败") }}

输入:

2022/10/25 10:30:48 类型断言转换失败
变量a存储值是整型,视图应用类型断言将其转换为字符串,后果报错了,这么玩是不行的,玩不起。
  1. 类型断言+switch实现数据类型判断
package mainimport ( "fmt")func TestFunc(value interface{}) { switch value.(type) { case int:  fmt.Printf("value=%v Type Int\n", value) case float32:  fmt.Printf("value=%v Type Float32\n", value) case float64:  fmt.Printf("value=%v Type Float64\n", value) case string:  fmt.Printf("value=%v Type string\n", value) }}func main() { TestFunc("hello") TestFunc(100) TestFunc(89.12)}

输入:

value=hello Type stringvalue=100 Type Intvalue=89.12 Type Float64
  1. 还能够将接口类型转换成另一个接口类型,上面的栗子是将A接口转换成B接口
package mainimport ( "fmt")type A interface{}type B interface{}func main() { var a A = 100 b := a.(B) fmt.Println(b)}
在之前的栗子,都是将接口类型转换成根本的数据类型,而这个栗子是将一个自定义的接口类型转换成另一个自定义的接口类型。
  1. 还能够将接口类型转成指针类型,看上面的栗子
package mainimport "fmt"func main() {    //定义接口类型的变量ainter var ainter interface{} num := 100 ainter = &num //将地址赋给接口变量 v, r := ainter.(*int) fmt.Println(v, r)}
下面的栗子中,应用类型断言将接口类型转成了int指针类型
  1. 接口能够嵌套吗?实战通知你
package mainimport "fmt"type action1 interface { insert()}type action2 interface { delete()}type actionInterface interface { action1 action2 query()}type Db struct { Data string}func (d Db) insert() { fmt.Print("插入数据...", d.Data)}func (d Db) delete() { fmt.Print("删除数据...", d.Data)}func (d Db) query() { fmt.Print("查问数据...", d.Data)}func main() { d := Db{Data: "hello"} d.query() d.delete() d.insert()}
通过下面的实战,接口是能够嵌套的,留神了,只有实现接口中所有的办法(含所有嵌套接口里的所有办法),那么才算是真正实现了接口。
  1. 实现error接口中的Error办法,来玩一个自定义谬误类型的栗子
package mainimport ( "fmt")type AddError struct { ErrorMsg string}func (m AddError) Error() string { return fmt.Sprintf("Add error %v", m.ErrorMsg)}func add(a int, b int) (int, error) { if a == 0 || b == 0 {  errinfo := fmt.Sprintf("a=%v, b=%v", a, b)  return 0, AddError{ErrorMsg: errinfo} } else {  return a + b, nil }}func main() { res, err := add(8, 0) fmt.Println(res, err)}
下面的栗子中,曾经隐式的实现了error接口中的Error办法
  1. 如果不玩自定义的谬误类型,也能够间接应用errors.New办法返回一个错误信息
package mainimport ( "errors" "fmt")func add(a int, b int) (int, error) { if a == 0 || b == 0 {  return 0, errors.New("不能为0") } else {  return a + b, nil }}func main() { res, err := add(9, 1) fmt.Println(res, err)}

本文转载于(喜爱的盆友关注咱们):https://mp.weixin.qq.com/s/Ac...