golang中結(jié)構(gòu)體嵌套接口的實現(xiàn)
在golang中結(jié)構(gòu)體A嵌套另一個結(jié)構(gòu)體B見的很多,可以擴展A的能力。
A不僅擁有了B的屬性,還擁有了B的方法,這里面還有一個字段提升的概念。
示例:
package main import "fmt" type Worker struct { ?? ?Name string ?? ?Age int ?? ?Salary } func (w Worker) fun1() { ?? ?fmt.Println("Worker fun1") } type Salary struct { ?? ?Money int } func (s Salary) fun1() { ?? ?fmt.Println("Salary fun1") } func (s Salary) fun2() { ?? ?fmt.Println("Salary fun2") } func main() { ?? ?s := Salary{} ?? ?w := Worker{Salary: s} ?? ?//w.Name ?? ?//w.Age ?? ?//w.Money ?? ?//w.Salary ?? ?//w.fun1() ?? ?//w.fun2() ?? ?//w.Salary.fun1() ?? ?//w.Salary.fun2() }
很明顯現(xiàn)在 Worker 強依賴與 Salary ,有時候我們希望 Worker 只依賴于一個接口,這樣只要實現(xiàn)了此接口的對象都可以傳遞進來。
優(yōu)化后:
package main import "fmt" type Inter1 interface { ?? ?fun1() ?? ?fun2() } type Worker struct { ?? ?Name string ?? ?Age int ?? ?Inter1 } func (w Worker) fun1() { ?? ?fmt.Println("Worker fun1") } type Salary struct { ?? ?Money int } func (s Salary) fun1() { ?? ?fmt.Println("Salary fun1") } func (s Salary) fun2() { ?? ?fmt.Println("Salary fun2") } func main() { ?? ?s := Salary{} ?? ?w := Worker{Inter1: s} ?? ?//w.Age ?? ?//w.Name ?? ?//w.fun1() ?? ?//w.fun2() ?? ?//w.Inter1 ?? ?//w.Inter1.fun1() ?? ?//w.Inter1.fun2() ?? ?// 無法訪問 Money 屬性,可以增加方法來實現(xiàn) }
Worker 依賴一個 Inter1 接口,只要實現(xiàn)了 Inter1 的對象都可以注入。
Worker 也實現(xiàn)了 Inter1 接口。
Worker 可以重新實現(xiàn) Inter1 接口的方法。
golang的context標準庫就是這樣實現(xiàn)的context之間的嵌套。
另外,需要注意的是,一個結(jié)構(gòu)體包含了一個接口,那么此結(jié)構(gòu)體自然就是這個接口的一個實現(xiàn),即便這個結(jié)構(gòu)體沒有實現(xiàn)任何方法
type man interface { ?? ?Eat(args ...any) } type dog struct { ?? ?man } func testDog() { ?? ?d := dog{} ?? ?d.Eat(1) }
顯然這里的調(diào)用會報錯。
golang接口的這種隱式的實現(xiàn)特性,會導(dǎo)致某個對象無意間就實現(xiàn)了某個接口,然而對于一些底層接口卻需要保持其封閉性,為了達到這個目的,通常的做法是,在接口中有特殊含義的方法,比如runtime.Error接口,注釋就說明了意圖
// The Error interface identifies a run time error. type Error interface { ?? ?error ?? ?// RuntimeError is a no-op function but ?? ?// serves to distinguish types that are run time ?? ?// errors from ordinary errors: a type is a ?? ?// run time error if it has a RuntimeError method. ?? ?RuntimeError() }
或者定義一個無法導(dǎo)出的方法,這樣在包外面就無法被實現(xiàn)了,比如testing.TB接口
// TB is the interface common to T, B, and F. type TB interface { ?? ?Cleanup(func()) ?? ?Error(args ...any) ?? ?Errorf(format string, args ...any) ?? ?Fail() ?? ?FailNow() ?? ?Failed() bool ?? ?Fatal(args ...any) ?? ?Fatalf(format string, args ...any) ?? ?Helper() ?? ?Log(args ...any) ?? ?Logf(format string, args ...any) ?? ?Name() string ?? ?Setenv(key, value string) ?? ?Skip(args ...any) ?? ?SkipNow() ?? ?Skipf(format string, args ...any) ?? ?Skipped() bool ?? ?TempDir() string ?? ?// A private method to prevent users implementing the ?? ?// interface and so future additions to it will not ?? ?// violate Go 1 compatibility. ?? ?private() }
第一種方法顯然只能防君子,不能防小人。
第二種方法看起來比較安全,但是結(jié)合我們上面的知識,如果使用結(jié)構(gòu)體來包含這個接口呢?是不是也能實現(xiàn)這個接口?
type MyTB struct { testing.TB }
顯然MyTB已經(jīng)實現(xiàn)了testing.TB,但是此時調(diào)用是會報錯的
func main() { tb := new(MyTB) tb.Fatal("hello", "world") }
實現(xiàn)其中的一個方法,再調(diào)用即可
func (p *MyTB) Fatal(args ...interface{}) { ?? ?fmt.Println(args...) } func main() { ?? ?tb := new(MyTB) ?? ?tb.Fatal("hello", "world") }
既然MyTB實現(xiàn)了testing.TB,那么就可以做隱式轉(zhuǎn)換
var tb testing.TB = new(MyTB) tb.Fatal("hello", "world")
到此這篇關(guān)于golang中結(jié)構(gòu)體嵌套接口的實現(xiàn)的文章就介紹到這了,更多相關(guān)golang 結(jié)構(gòu)體嵌套接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang?throttled基于GCRA速率限制庫使用探索
這篇文章主要為大家介紹了Golang?throttled基于GCRA速率限制庫使用實例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例
這篇文章主要為大家介紹了Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06淺析Go中函數(shù)的健壯性,panic異常處理和defer機制
這篇文章主要為大家詳細介紹了Go中函數(shù)的健壯性,panic異常處理和defer機制的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-10-10golang常用庫之gorilla/mux-http路由庫使用詳解
這篇文章主要介紹了golang常用庫之gorilla/mux-http路由庫使用,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Go語言利用ffmpeg轉(zhuǎn)hls實現(xiàn)簡單視頻直播
這篇文章主要為大家介紹了Go語言利用ffmpeg轉(zhuǎn)hls實現(xiàn)簡單視頻直播,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04