Go 18.0 专业五


接口

<h1>单元目标</h1> <ul> <li>使用接口来实现多态</li> </ul> <h1>接口</h1> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172cff30b3bf3900~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172d09e478c2d659~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <h3>3,使用接口来实现多态</h3> <p>接口的意义是对其他类型的一个概括,接口内可以定义很多个方法,谁将这些方法实现,就可以认为是实现了该接口。Go语言的多态,主要是通过接口来实现。</p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172cff886f91b5de~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <pre><code>package main import ( "fmt" ) func main() { h := Haojiahuo{name: "好家伙"} fmt.Println(h.name) l := Laolitou{name: "老李头"} fmt.Println(l.name) //testInterface 需要参数类型为Kongfu接口类型的参数 //h实现了Kongfu接口的方法 //h就是这个接口的实现 就可以作为这个函数的参数 testInterface(h) var kf Kongfu kf = h kf.Toad() l.PlayGame() } //测试方法 func testInterface(k Kongfu) { k.Toad() k.SixSwords() } //定义接口 type Kongfu interface { Toad() //蛤蟆功 SixSwords() //六脉神剑 } //实现类 type Haojiahuo struct { name string } //实现类 type Laolitou struct { name string } //实现方法 func (o Haojiahuo) Toad() { fmt.Println(o.name, "实现了蛤蟆功..") } //实现方法 func (o Haojiahuo) SixSwords() { fmt.Println(o.name, "实现了六脉神剑..") } //实现方法 func (f Laolitou) Toad() { fmt.Println(f.name, "也实现了蛤蟆功..") } //实现方法 func (f Laolitou) SixSwords() { fmt.Println(f.name, "也实现了六脉神剑.") } //实现自己的方法 func (f Laolitou) PlayGame() { fmt.Println(f.name, "玩游戏..") }</code></pre> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172d0a7be4a75605~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <p>使用接口对方法进行约束,然后让方法实现接口,这样规范了方法。通过使用同样的接口名称,但是在调用的时候使用不同的类,实现执行不同的方法。这样就实现了Go语言中的多态。</p> <h2>空接口</h2> <p>空接口就是不包含任何方法的接口,所有的类型都可以实现空接口,因此空接口可以实现存储任意类型的数据, 谁实现它就被看作是谁的实现类。</p> <pre><code>package main import ( "fmt" ) func main() { Test1(0)//使用int类型做为参数传入到函数 Test1("ceshi")//使用string类型做为参数传入到函数 } //空接口 type T interface { } //定义一个函数 接收Test接口类型的数据 func Test1(t T) { fmt.Println(t) }</code></pre> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172d0bf93699c9bd~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <p>可以将空接口类型写为<code>interface{}</code> 这种类型可以理解为任何类型。类似其他语言中的<code>object</code>。</p> <h2>空接口的使用</h2> <p>空接口既然可以传任意类型,利用这个特性可以把空接口interface{}当做容器使用。</p> <pre><code>func Test() { //创建一个map类型 key为string val为空接口,这样值就可以存储任意类型了 m := make(map[string]interface{}) m["a"] = "zhangsan" m["b"] = 1.1 m["c"] = true fmt.Println(m) } package main import "fmt" // 字典结构 type Dictionary struct { data map[string]interface{} // 数据key为string值为interface{}类型 } // 获取值 func (d *Dictionary) GetData(key string) interface{} { return d.data[key] } // 设置值 func (d *Dictionary) SetData(key string, value interface{}) { d.data[key] = value } // 创建一个字典 func NewDict() *Dictionary { return &amp;Dictionary{ data: make(map[string]interface{}),//map类型使用前需要初始化,所以需要使用make创建 防止空指针异常。 } } func main() { // 创建字典实例 dict := NewDict() // 添加数据 dict.SetData("001", "第一条数据") dict.SetData("002", 3.1415) dict.SetData("003", false) // 获取值 d := dict.GetData("001") fmt.Println(d) }</code></pre> <h2>Go语言中的错误</h2> <p>错误和异常不同,错误是在程序中正常存在的,可以预知的失败在意料之中。而异常通常指在不应该出现问题的地方出现问题,比如空指针,这在人们的意料之外。go语言没有 <code>try......catch</code> 这样的方式来捕获异常所以Go定义属于自己的一种错误类型,用error表示错误。</p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172d0d5af5ad8444~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <p>例如:我们在读取一个不存在的文件时候。如果文件正常存在就返回文件的内容,否则就返回一个err信息。</p> <pre><code>package main import ( "fmt" "io/ioutil" ) func main() { //使用io/ioutil包下的读取文件方法 conent, err := ioutil.ReadFile("test.txt") if err != nil { fmt.Println(err)//打印错误信息 } else { fmt.Println(string(conent))//返回正常信息 } }</code></pre> <p>通常情况一个函数如果有错误,都会在返回值最后一个,返回一个error类型的错误,根据这个值来判断是否是非nil的值,如果是nil表示没有错误,如果nil不为空,则需要进行错误处理。</p> <p>error的定义是一个接口,接口内部包含一个返回字符串类型的方法Error()</p> <pre><code>type error interface { Error() string }</code></pre> <p>知道了error的定义是一个接口类型,那么只要实现了这个接口 都可以用来处理错误信息。来返回一个错误提示给用户。Go语言也提供了一个内置包errors ,来创建一个错误对象。</p> <p><img src="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/20/172d2486f5285d9b~tplv-t2oaga2asx-zoom-in-crop-mark:3024:0:0:0.awebp" alt="" /></p> <pre><code>package main import ( "errors" "fmt" ) func main() { err := errors.New("错误信息...") fmt.Println(err) num, err2 := Calculation(0) fmt.Println(num, err2) } //通过内置errors包创建错误对象来返回 func Calculation(divisor int) (int, error) { if divisor == 0 { return 0, errors.New("错误:除数不能为零.") } return 100 / divisor, nil }</code></pre>

页面列表

ITEM_HTML