欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

從零開始學Golang的接口

 更新時間:2022年03月24日 11:09:23   作者:咖啡色的羊駝  
本文主要介紹了從零開始學Golang的接口,原文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

接口在面向?qū)ο缶幊讨惺墙?jīng)常使用的招式,也是體現(xiàn)多態(tài)很重要的手段。
是的。Golang中也有接口這玩意兒。

1.為什么需要接口?

多數(shù)情況下,數(shù)據(jù)可能包含不同的類型,卻會有一個或者多個共同點,這些共同點就是抽象的基礎(chǔ)。前文講到的Golang繼承解決的是is-a的問題,單一繼承的關(guān)系。但是當不同的父類具有相同的行為的時候,單一繼承就沒法解決了。

于是乎,接口出現(xiàn)了。接口可以理解為某一個方面的抽象,可以是多對一的(多個類型實現(xiàn)一個接口),這也是多態(tài)的體現(xiàn)。解決了上文一對一的問題。

2.接口是什么?如何定義?

是什么
接口是一組僅包含方法名、參數(shù)、返回值的未具體實現(xiàn)的方法的集合。

如果實現(xiàn)了接口的所有方法,則認為實現(xiàn)了該接口,無需在該類型上顯示的添加聲明。

這個解釋下,加深印象,在php中接口是長這樣的:

//定義接口
interface base{
? ?public function getName();
}
?
//學生類
class student implements base{
? ?public function getName(){
? ? ? echo "咖啡色的羊駝";
? ?}
}

這里有個關(guān)鍵字:implements。

這樣的聲明稱之為顯示的,而在Golang中接口是隱式地實現(xiàn)。(埋個伏筆看下文)

定義

type interfaceName interface {?
?? ?// 方法列表?
? ? GetName() string
}?

3.接口實戰(zhàn)初體驗

實際編程中呢,接口的命名大伙兒喜歡使用er結(jié)尾。當然這個看個人喜好。

上代碼:

?? ?package main

?? ?import (
?? ??? ?"fmt"
?? ?)
?? ?
?? ?// 定義一個接口
?? ?type People interface {
?? ??? ?ReturnName() string
?? ?}
?? ?
?? ?// 定義一個結(jié)構(gòu)體
?? ?type Student struct {
?? ??? ?Name string
?? ?}
?? ?
?? ?// 定義結(jié)構(gòu)體的一個方法。
?? ?// 突然發(fā)現(xiàn)這個方法同接口People的所有方法(就一個),此時可直接認為結(jié)構(gòu)體Student實現(xiàn)了接口People
?? ?func (s Student) ReturnName() string {
?? ??? ?return s.Name
?? ?}
?? ?
?? ?func main() {
?? ??? ?cbs := Student{Name:"咖啡色的羊駝"}
?? ?
?? ??? ?var a People
?? ??? ?// 因為Students實現(xiàn)了接口所以直接賦值沒問題
?? ??? ?// 如果沒實現(xiàn)會報錯:cannot use cbs (type Student) as type People in assignment:Student does not implement People (missing ReturnName method)
?? ??? ?a = cbs ? ? ??
?? ??? ?name := a.ReturnName()?
?? ??? ?fmt.Println(name) // 輸出"咖啡色的羊駝"
?? ?}

4.如何測試是否已實現(xiàn)該接口?

使用接口特有的斷言判斷來實現(xiàn)(下文還會再次提到,加深印象)。

語法:x.(T)
這樣的語法只適應(yīng)于x是interface類型

接著上文例子,繼續(xù)上代碼:

?? ?// 由于x.(T)只能是接口類型判斷,所以傳參時候,傳入的是接口類型
?? ?// 為何test的類型可以是一個空接口?埋伏筆下文便知。
?? ?func CheckPeople(test interface{}) {
?? ??? ?if _, ok := test.(People); ok {
?? ? ? ??? ?fmt.Printf("Student implements People")
?? ??? ?}
?? ?}

?? ?
?? ?func main() {
?? ??? ?cbs := Student{Name:"咖啡色的羊駝"}
?? ??? ?CheckPeople(cbs) // Student implements People
?? ?}

5.空接口&類型斷言

空接口

空接口就是不包含任何方法的接口。正因為如此,所有的類型都實現(xiàn)了空接口。

雖然空接口起不到任何作用,但是空接口在需要存儲任何類型數(shù)值的時候非常有用,這也回答了上文的問題,因為空接口可以存儲任意類型的數(shù)據(jù)。

?? ?// 定義cbs為空接口
? ? var cbs interface{}
? ? var i int = 5
? ? var s string = "Hello world"
? ? // cbs可以存儲任意類型的數(shù)值
? ? cbs = i
? ? cbs = s

類型斷言

既然空接口可以存儲任意類型,那么如何區(qū)分不同的類型?
常用的有兩種方法:Comma-ok斷言、switch判斷。

上代碼:

?? ?package main
?? ?
?? ?import (
?? ??? ?"fmt"
?? ?)
?? ?
?? ?// 定義一個結(jié)構(gòu)體
?? ?type Student struct {
?? ??? ?Name string
?? ?}
?? ?
?? ?// 類型斷言
?? ?func main() {
?? ? ? ?Params := make([]interface{}, 3)
?? ??? ?Params[0] = 88 ? ? ? ? ? ? ? ? ? // 整型
?? ??? ?Params[1] = "咖啡色的羊駝" ? ? ? ? // 字符串
?? ??? ?Params[2] = Student{Name: "cbs"} // 自定義結(jié)構(gòu)體類型
?? ??? ?
?? ??? ?// Comma-ok斷言
?? ??? ?for index, v := range Params {
?? ??? ??? ?if _, ok := v.(int); ok {
?? ??? ??? ??? ?fmt.Printf("Params[%d] 是int類型 \n", index)
?? ??? ??? ?} else if _, ok := v.(string); ok {
?? ??? ??? ??? ?fmt.Printf("Params[%d] 是字符串類型\n", index)
?? ??? ??? ?} else if _, ok := v.(Student); ok {
?? ??? ??? ??? ?fmt.Printf("Params[%d] 是自定義結(jié)構(gòu)體類型\n", index)
?? ??? ??? ?} else {
?? ??? ??? ??? ?fmt.Printf("list[%d] 未知類型\n", index)
?? ??? ??? ?}
?? ??? ?}
?? ??? ?
?? ??? ?// switch判斷
?? ??? ?for index, v := range Params {
?? ??? ??? ?switch ?value := v.(type) {
?? ? ? ? ? ?case int:
?? ? ? ? ? ? ? ?fmt.Printf("Params[%d] 是int類型, 值:%d \n", index,value)
?? ? ? ? ? ?case string:
?? ? ? ? ? ? ? ?fmt.Printf("Params[%d] 是字符串類型, 值:%s\n", index,value)
?? ? ? ? ? ?case Student:
?? ? ? ? ? ? ? ?fmt.Printf("Params[%d] 是Person類型, 值:%s\n", index,value)
?? ? ? ? ? ?default:
?? ? ? ? ? ? ? ?fmt.Printf("list[%d] 未知類型\n", index)
?? ? ? ? ? ?}?
?? ??? ?
?? ??? ?} ?
?? ?}

6.接口零值

接口的零值是nil

    package main
    
    import (
        "fmt"
    )
    
    type People interface {  
        GetName() string
    }
    
    // 輸出 "cbs is nil 類型"
    func main() {  
        var cbs People
        if cbs == nil {
            fmt.Println("cbs is nil 類型")  
        }
    }

7.一個類型實現(xiàn)多個接口

    package main
    
    import (
        "fmt"
    )
    
    type People interface {
        ReturnName() string
    }
    
    type Role interface {
        ReturnRole() string
    }
    
    type Student struct {
        Name string
    }
    
    func (s Student) ReturnName() string {
        return s.Name
    }
    
    func (s Student) ReturnRole() string {
        return "學生"
    }
    
    func main() {
        cbs := Student{Name: "咖啡色的羊駝"}
    
        var a People  // 定義a為People接口類型
        var b Role    // 定義b為Role接口類型
        
        a = cbs // 由于Student實現(xiàn)了People所有方法,所以接口實現(xiàn)成功,可直接賦值
        b = cbs // 由于Student實現(xiàn)了Role所有方法,所以接口實現(xiàn)成功,可直接賦值
        
        name := a.ReturnName()
        fmt.Println(name) // 輸出"咖啡色的羊駝"
    
        role := b.ReturnRole()
        fmt.Println(role) // 輸出"學生"
    }

也說明一個東西:實現(xiàn)了某個接口的類型,還可以有其它的方法。只要是方法實現(xiàn)包含接口的即可。

8.指針與值類型實現(xiàn)接口的區(qū)別

    package main
    
    import (
        "fmt"
    )
    
    type People interface {
        ReturnName() string
    }
    
    type Student struct {
        Name string
    }
    
    type Teacher struct {
        Name string
    }
    
    func (s Student) ReturnName() string {
        return s.Name
    }
    
    func (t *Teacher) ReturnName() string {
        return t.Name
    }
    
    func main() {
        cbs := Student{Name: "咖啡色的羊駝"}
        sss := Teacher{Name: "咖啡色的羊駝的老師"}
    
        // 值類型
        var a People
        a = cbs 
        name := a.ReturnName()
        fmt.Println(name)
    
        // 指針類型
        // a = sss <- 這樣寫不行?。?!
        a = &sss // 由于是指針類型,所以賦值的時候需要加上&
        name = a.ReturnName()
        fmt.Println(name) // 輸出"咖啡色的羊駝的老師"
    }

"a = sss"這樣寫會發(fā)生報錯:

    cannot use sss (type Teacher) as type People in assignment:
    Teacher does not implement People (ReturnName method has pointer receiver)

因為是Teacher的指針實現(xiàn)了ReturnName方法,Teacher本身沒實現(xiàn)。

9.接口嵌套

類似于PHP的接口繼承,Golang也有它的接口嵌套。

    package main
    
    import (
        "fmt"
    )
    
    type People interface {
        ReturnName() string
    }
    
    type Role interface {
        People // 接口嵌套
        ReturnRole() string
    }
    
    type Student struct {
        Name string
    }
    
    func (s Student) ReturnName() string {
        return s.Name
    }
    
    func (s Student) ReturnRole() string {
        return "學生"
    }
    
    func main() {
        cbs := Student{Name: "咖啡色的羊駝"}
        
        var a Role
        a = cbs 
        name := a.ReturnName()
        fmt.Println(name)
    
        role := a.ReturnRole()
        fmt.Println(role) 
    }

到此這篇關(guān)于從零開始學Golang的接口的文章就介紹到這了,更多相關(guān)Golang 接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang創(chuàng)建文件目錄os.Mkdir,os.MkdirAll的區(qū)別說明

    golang創(chuàng)建文件目錄os.Mkdir,os.MkdirAll的區(qū)別說明

    本文主要講述os.Mkdir、os.MkdirAll區(qū)別以及在創(chuàng)建文件目錄過程中的一些其他技巧,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 深入了解Golang官方container/list原理

    深入了解Golang官方container/list原理

    在?Golang?的標準庫?container?中,包含了幾種常見的數(shù)據(jù)結(jié)構(gòu)的實現(xiàn),其實是非常好的學習材料,本文主要為大家介紹了container/list的原理與使用,感興趣的可以了解一下
    2023-08-08
  • Go語言快速入門圖文教程

    Go語言快速入門圖文教程

    Go是 Goolge 開發(fā)的一種靜態(tài)型、編譯型、并發(fā)型,并具有垃圾回收功能的語言,Go 語言上手非常容易,它的風格類似于 C 語言,Go 語言號稱是互聯(lián)網(wǎng)時代的 C 語言,那么它到底有多火呢,一起看看吧
    2021-05-05
  • 解析Golang中的鎖競爭問題

    解析Golang中的鎖競爭問題

    這篇文章主要介紹了golang中的鎖競爭問題,本文通過實例代碼給大家詳細講解,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • 使用Golang實現(xiàn)WebSocket心跳機制

    使用Golang實現(xiàn)WebSocket心跳機制

    WebSocket是一種在客戶端和服務(wù)器之間實現(xiàn)全雙工通信的協(xié)議,它允許實時地傳輸數(shù)據(jù),并且比傳統(tǒng)的HTTP請求更加高效,在使用Golang構(gòu)建WebSocket應(yīng)用程序時,一個重要的考慮因素是如何實現(xiàn)心跳機制,所以本文將探討如何使用Golang實現(xiàn)WebSocket心跳
    2023-11-11
  • Ruby序列化和持久化存儲(Marshal、Pstore)操作方法詳解

    Ruby序列化和持久化存儲(Marshal、Pstore)操作方法詳解

    這篇文章主要介紹了Ruby序列化和持久化存儲(Marshal、Pstore)操作方法詳解,包括Ruby Marshal序列化,Ruby Pstore存儲,需要的朋友可以參考下
    2022-04-04
  • Go高級特性探究之recover捕獲panic詳解

    Go高級特性探究之recover捕獲panic詳解

    在Go語言中,當程序出現(xiàn)panic(即運行時錯誤)時,程序會立即停止當前的執(zhí)行流程,而recover函數(shù)的作用就是捕獲這個panic,下面就來看看具體是怎么操作的吧
    2023-06-06
  • 詳解在Go語言單元測試中如何解決Redis存儲依賴問題

    詳解在Go語言單元測試中如何解決Redis存儲依賴問題

    在編寫單元測試時,除了?MySQL?這個外部存儲依賴,Redis?應(yīng)該是另一個最為常見的外部存儲依賴了,本文就來講解下如何解決?Redis?外部依賴,文章通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-08-08
  • Go語言中的方法定義用法分析

    Go語言中的方法定義用法分析

    這篇文章主要介紹了Go語言中的方法定義用法,實例分析了方法的定義及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Go實現(xiàn)快速生成固定長度的隨機字符串

    Go實現(xiàn)快速生成固定長度的隨機字符串

    這篇文章主要為大家詳細介紹了怎樣在Go中簡單快速地生成固定長度的隨機字符串,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以學習一下
    2022-10-10

最新評論