乐趣区

关于go:下篇一文玩转Go接口

  1. 空接口既然能够存储任意类型的值,那么从空接口获取到的值是否能够间接应用?看上面栗子
package main

import ("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 main

import ("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 true
100 true
  1. 类型断言新姿态:当应用一个值承受断言后果时,则会间接返回断言后的值
package main

import ("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 main

import (
 "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 main

import ("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 string
value=100 Type Int
value=89.12 Type Float64
  1. 还能够将接口类型转换成另一个接口类型,上面的栗子是将 A 接口转换成 B 接口
package main

import ("fmt")

type A interface{}

type B interface{}

func main() {
 var a A = 100
 b := a.(B)
 fmt.Println(b)
}

在之前的栗子,都是将接口类型转换成根本的数据类型,而这个栗子是将一个自定义的接口类型转换成另一个自定义的接口类型。

  1. 还能够将接口类型转成指针类型,看上面的栗子
package main

import "fmt"

func main() {
    // 定义接口类型的变量 ainter
 var ainter interface{}
 num := 100
 ainter = &num // 将地址赋给接口变量

 v, r := ainter.(*int)
 fmt.Println(v, r)
}

下面的栗子中,应用类型断言将接口类型转成了 int 指针类型

  1. 接口能够嵌套吗?实战通知你
package main

import "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 main

import ("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 main

import (
 "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…

退出移动版