亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

    Go語言中類型與接口有什么關(guān)系

    在Go語言中,類型和接口之間有一對多和多對一的關(guān)系。一個(gè)類型可以同時(shí)實(shí)現(xiàn)多個(gè)接口,而接口間彼此獨(dú)立,不知道對方的實(shí)現(xiàn)。多個(gè)類型也可以實(shí)現(xiàn)相同的接口:一個(gè)接口的方法,不一定需要由一個(gè)類型完全實(shí)現(xiàn),接口的方法可以通過在類型中嵌入其他類型或者結(jié)構(gòu)體來實(shí)現(xiàn)。也就是說,使用者并不關(guān)心某個(gè)接口的方法是通過一個(gè)類型完全實(shí)現(xiàn)的,還是通過多個(gè)結(jié)構(gòu)嵌入到一個(gè)結(jié)構(gòu)體中拼湊起來共同實(shí)現(xiàn)的。

    Go語言中類型與接口有什么關(guān)系

    本教程操作環(huán)境:windows7系統(tǒng)、GO 1.18版本、Dell G3電腦。

    Go語言類型與接口的關(guān)系

    在Go語言中類型和接口之間有一對多和多對一的關(guān)系,下面將列舉出這些常見的概念,以方便讀者理解接口與類型在復(fù)雜環(huán)境下的實(shí)現(xiàn)關(guān)系。

    一個(gè)類型可以實(shí)現(xiàn)多個(gè)接口

    一個(gè)類型可以同時(shí)實(shí)現(xiàn)多個(gè)接口,而接口間彼此獨(dú)立,不知道對方的實(shí)現(xiàn)。

    網(wǎng)絡(luò)上的兩個(gè)程序通過一個(gè)雙向的通信連接實(shí)現(xiàn)數(shù)據(jù)的交換,連接的一端稱為一個(gè) Socket。Socket 能夠同時(shí)讀取和寫入數(shù)據(jù),這個(gè)特性與文件類似。因此,開發(fā)中把文件和 Socket 都具備的讀寫特性抽象為獨(dú)立的讀寫器概念。

    Socket 和文件一樣,在使用完畢后,也需要對資源進(jìn)行釋放。

    把 Socket 能夠?qū)懭霐?shù)據(jù)和需要關(guān)閉的特性使用接口來描述,請參考下面的代碼:

    type Socket struct { } func (s *Socket) Write(p []byte) (n int, err error) {     return 0, nil } func (s *Socket) Close() error {     return nil }
    登錄后復(fù)制

    Socket 結(jié)構(gòu)的 Write() 方法實(shí)現(xiàn)了 io.Writer 接口:

    type Writer interface {     Write(p []byte) (n int, err error) }
    登錄后復(fù)制

    同時(shí),Socket 結(jié)構(gòu)也實(shí)現(xiàn)了 io.Closer 接口:

    type Closer interface {     Close() error }
    登錄后復(fù)制

    使用 Socket 實(shí)現(xiàn)的 Writer 接口的代碼,無須了解 Writer 接口的實(shí)現(xiàn)者是否具備 Closer 接口的特性。同樣,使用 Closer 接口的代碼也并不知道 Socket 已經(jīng)實(shí)現(xiàn)了 Writer 接口,如下圖所示。

    Go語言中類型與接口有什么關(guān)系
    圖:接口的使用和實(shí)現(xiàn)過程

    在代碼中使用 Socket 結(jié)構(gòu)實(shí)現(xiàn)的 Writer 接口和 Closer 接口代碼如下:

    // 使用io.Writer的代碼, 并不知道Socket和io.Closer的存在 func usingWriter( writer io.Writer){     writer.Write( nil ) } // 使用io.Closer, 并不知道Socket和io.Writer的存在 func usingCloser( closer io.Closer) {     closer.Close() } func main() {     // 實(shí)例化Socket     s := new(Socket)     usingWriter(s)     usingCloser(s) }
    登錄后復(fù)制

    usingWriter() 和 usingCloser() 完全獨(dú)立,互相不知道對方的存在,也不知道自己使用的接口是 Socket 實(shí)現(xiàn)的。

    多個(gè)類型可以實(shí)現(xiàn)相同的接口

    一個(gè)接口的方法,不一定需要由一個(gè)類型完全實(shí)現(xiàn),接口的方法可以通過在類型中嵌入其他類型或者結(jié)構(gòu)體來實(shí)現(xiàn)。也就是說,使用者并不關(guān)心某個(gè)接口的方法是通過一個(gè)類型完全實(shí)現(xiàn)的,還是通過多個(gè)結(jié)構(gòu)嵌入到一個(gè)結(jié)構(gòu)體中拼湊起來共同實(shí)現(xiàn)的。

    Service 接口定義了兩個(gè)方法:一個(gè)是開啟服務(wù)的方法(Start()),一個(gè)是輸出日志的方法(Log())。使用 GameService 結(jié)構(gòu)體來實(shí)現(xiàn) Service,GameService 自己的結(jié)構(gòu)只能實(shí)現(xiàn) Start() 方法,而 Service 接口中的 Log() 方法已經(jīng)被一個(gè)能輸出日志的日志器(Logger)實(shí)現(xiàn)了,無須再進(jìn)行 GameService 封裝,或者重新實(shí)現(xiàn)一遍。所以,選擇將 Logger 嵌入到 GameService 能最大程度地避免代碼冗余,簡化代碼結(jié)構(gòu)。詳細(xì)實(shí)現(xiàn)過程如下:

    // 一個(gè)服務(wù)需要滿足能夠開啟和寫日志的功能 type Service interface {     Start()  // 開啟服務(wù)     Log(string)  // 日志輸出 } // 日志器 type Logger struct { } // 實(shí)現(xiàn)Service的Log()方法 func (g *Logger) Log(l string) { } // 游戲服務(wù) type GameService struct {     Logger  // 嵌入日志器 } // 實(shí)現(xiàn)Service的Start()方法 func (g *GameService) Start() { }
    登錄后復(fù)制

    代碼說明如下:

    • 第 2 行,定義服務(wù)接口,一個(gè)服務(wù)需要實(shí)現(xiàn) Start() 方法和日志方法。

    • 第 8 行,定義能輸出日志的日志器結(jié)構(gòu)。

    • 第 12 行,為 Logger 添加 Log() 方法,同時(shí)實(shí)現(xiàn) Service 的 Log() 方法。

    • 第 17 行,定義 GameService 結(jié)構(gòu)。

    • 第 18 行,在 GameService 中嵌入 Logger 日志器,以實(shí)現(xiàn)日志功能。

    • 第 22 行,GameService 的 Start() 方法實(shí)現(xiàn)了 Service 的 Start() 方法。

    此時(shí),實(shí)例化 GameService,并將實(shí)例賦給 Service,代碼如下:

    var s Service = new(GameService) s.Start() s.Log(“hello”)
    登錄后復(fù)制

    s 就可以使用 Start() 方法和 Log() 方法,其中,Start() 由 GameService 實(shí)現(xiàn),Log() 方法由 Logger 實(shí)現(xiàn)。

    贊(0)
    分享到: 更多 (0)
    網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號