日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GoLang之接口interface

發布時間:2023/12/18 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GoLang之接口interface 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 接口interface
    • 1.接口介紹
    • 2.接口定義
      • 2.1定義要求
      • 2.2接口可以嵌入到其他接口里但必須得匿名
        • 2.2.1接口里可以含一個接口時
        • 2.2.2接口里可以含多個接口時
      • 2.3接口沒有數據字段
      • 2.4接口可以嵌入到結構體struct里
      • 2.5空接口可以作為任何類型數據的容器
      • 2.6接口命名習慣以 er 結尾
      • 2.7實現接口的所有方法即可實現接口
        • 2.7.1沒有嵌套其他接口時
        • 2.7.1嵌套其他接口時正確實現
        • 2.7.1嵌套其他接口時錯誤實現
      • 2.8接口是一個或多個方法簽名的集合
      • 2.9一個類型可以實現多個接口
        • 2.9.1接口內方法不一樣時
        • 2.9.2接口內方法一樣時
      • 2.10接口同樣支持匿名方法
      • 2.11只有當接口存儲的類型和對象都為nil時接口才等于nil
      • 2.12接口類型的變量可使用其實例的方法
      • 2.13接口類型的變量不可以使用其實例的字段
      • 2.14值接收者實現接口
      • 2.15指針接收者實現接口
      • 2.16多個類型實同一接口
      • 2.17結構體中方法+結構體中所嵌套的結構體的方法來實現接口
    • 3.使用接口的原因
    • 4.接口的方法錯誤定義
    • 5.空接口
      • 5.1空結構體占用16字節
      • 5.2類型斷言
        • 5.1定義
        • 5.2v,ok=x.(Y)應用
        • 5.3type switch 語句介紹
        • 5.4結合switch語句

接口interface

1.接口介紹

在Go語言中接口(interface)是一種類型,一種抽象的類型;
interface是一組method的集合,是duck-type programming的一種體現。接口做的事情就像是定義一個協議(規則),只要一臺機器有洗衣服和甩干的功能,我就稱它為洗衣機。不關心屬性(數據),只關心行為(方法);
為了保護你的Go語言職業生涯,請牢記接口(interface)是一種類型;

2.接口定義

2.1定義要求

2.2接口可以嵌入到其他接口里但必須得匿名

2.2.1接口里可以含一個接口時

type Phone interface {demo//不會報錯 } type demo interface {} type Phone interface {aa demo//會編譯報錯 } type demo interface {}

2.2.2接口里可以含多個接口時

// Sayer 接口 type Sayer interface {say() }// Mover 接口 type Mover interface {move() }// 接口嵌套 type animal interface {SayerMover }type cat struct {name string }func (c cat) say() {fmt.Println("喵喵喵") }func (c cat) move() {fmt.Println("貓會動") }func main() {var x animalx = cat{name: "花花"}x.move()x.say() }

2.3接口沒有數據字段

接口只有方法聲明,沒有實現,沒有數據字段

2.4接口可以嵌入到結構體struct里

2.5空接口可以作為任何類型數據的容器

2.6接口命名習慣以 er 結尾

2.7實現接口的所有方法即可實現接口

實現接口條件:
接口被實現的條件一:接口的方法與實現接口的類型方法格式一致
接口被實現的條件二:接口中所有方法均被實現
任何類型的方法集中只要擁有該接口’對應的全部方法’簽名就表示它 “實現” 了該接口,無須在該類型上顯式聲明實現了哪個接口,這稱為Structural Typing;
所謂對應方法,是指有相同名稱、參數列表 (不包括參數名) 以及返回值;
當然該類型還可以有其他方法

2.7.1沒有嵌套其他接口時

// Sayer 接口 type Sayer interface {say() } type dog struct{}type cat struct{} // dog實現了Sayer接口 func (d dog) say() {fmt.Println("汪汪汪") }// cat實現了Sayer接口 func (c cat) say() {fmt.Println("喵喵喵") }

2.7.1嵌套其他接口時正確實現

type Sayer interface {Listersay() } type Lister interface {lis() }type cat struct{}// dog實現了Sayer接口 func (d cat) say() {fmt.Println("汪汪汪") }// cat實現了Sayer接口 func (c cat) lis() {fmt.Println("喵喵喵") }func main() {var x Sayer // 聲明一個Sayer類型的變量xa := cat{} // 實例化一個catx = a // 會報錯,原因缺少say方法x.say() // 汪汪汪x.lis() }

2.7.1嵌套其他接口時錯誤實現

type Sayer interface {Listersay() } type Lister interface {lis() } type dog struct{}type cat struct{}// dog實現了Sayer接口 func (d dog) say() {fmt.Println("汪汪汪") }// cat實現了Sayer接口 func (c cat) lis() {fmt.Println("喵喵喵") }func main() {var x Sayer // 聲明一個Sayer類型的變量xa := cat{} // 實例化一個catb := dog{} // 實例化一個dogx = a // 會報錯,原因缺少say方法x = b // 會報錯,原因缺少lis方法x.say() // 汪汪汪}

2.8接口是一個或多個方法簽名的集合

2.9一個類型可以實現多個接口

2.9.1接口內方法不一樣時

// Sayer 接口 type Sayer interface {say() }// Mover 接口 type Mover interface {move() }type dog struct {name string }// 實現Sayer接口 func (d dog) say() {fmt.Printf("%s會叫汪汪汪\n", d.name) }// 實現Mover接口 func (d dog) move() {fmt.Printf("%s會動\n", d.name) }func main() {var x Sayervar y Movervar a = dog{name: "旺財"}x = ay = ax.say() //輸出:旺財會叫汪汪汪y.move() //輸出:旺財會動 }

2.9.2接口內方法一樣時

// Sayer 接口 type Sayer interface {say() }// Mover 接口 type Mover interface {say() }type dog struct {name string }// 實現Sayer接口 func (d dog) say() {fmt.Printf("%s會叫汪汪汪\n", d.name) }func main() {var x Sayervar y Movervar a = dog{name: "旺財"}x = ay = ax.say() //輸出:旺財會叫汪汪汪y.say()//輸出:旺財會叫汪汪汪 }

2.10接口同樣支持匿名方法

type Phone interface {func() string //匿名時候需要加funcsay() string //不匿名時候不用加func }

2.11只有當接口存儲的類型和對象都為nil時接口才等于nil

2.12接口類型的變量可使用其實例的方法

接口類型的變量可使用其實例的方法 ,但是不可以使用其實例的字段

// Sayer 接口 type Sayer interface {say() } type dog struct {a int }type cat struct{}// dog實現了Sayer接口 func (d dog) say() {fmt.Println("汪汪汪") }// cat實現了Sayer接口 func (c cat) say() {fmt.Println("喵喵喵") }func main() {var x Sayer // 聲明一個Sayer類型的變量xa := cat{} // 實例化一個catb := dog{} // 實例化一個dogx = a // 可以把cat實例直接賦值給xx.say() // 喵喵喵x = b // 可以把dog實例直接賦值給xx.say() // 汪汪汪}

2.13接口類型的變量不可以使用其實例的字段

// Sayer 接口 type Sayer interface {say() } type dog struct {a int }// dog實現了Sayer接口 func (d dog) say() {fmt.Println("汪汪汪") }func main() {var x Sayer b := dog{a :4,}x = b x.say() fmt.Println(x.a) //會編譯出錯 }

2.14值接收者實現接口

從下面的代碼中我們可以發現,使用值接收者實現接口之后,不管是dog結構體還是結構體指針dog類型的變量都可以賦值給該接口變量。因為Go語言中有對指針類型變量求值的語法糖,dog指針fugui內部會自動求值fugui

type Mover interface {move() }type dog struct{}func (d dog) move() {fmt.Println("狗會動") }func main() {var x Movervar wangcai = dog{} // 旺財是dog類型x = wangcai // x可以接收dog類型var fugui = &dog{} // 富貴是*dog類型x = fugui // x可以接收*dog類型x.move() }

2.15指針接收者實現接口

此時實現Mover接口的是dog類型,所以不能給x傳入dog類型的wangcai,此時x只能存儲dog類型的值

type Mover interface {move() }type dog struct{}func (d *dog) move() {fmt.Println("狗會動") }func main() {var x Movervar wangcai = dog{} // 旺財是dog類型x = wangcai // 這一行會會議報錯var fugui = &dog{} // 富貴是*dog類型x = fugui // x可以接收*dog類型x.move() }

2.16多個類型實同一接口

// Mover 接口 type Mover interface {move() } type dog struct {name string }type car struct {brand string }// dog類型實現Mover接口 func (d dog) move() {fmt.Printf("%s會跑\n", d.name) }// car類型實現Mover接口 func (c car) move() {fmt.Printf("%s速度70邁\n", c.brand) } func main() {var x Movervar a = dog{name: "旺財"}var b = car{brand: "保時捷"}x = ax.move() //輸出:旺財會跑x = bx.move() //輸出:保時捷速度70邁 }

2.17結構體中方法+結構體中所嵌套的結構體的方法來實現接口

接口的方法可以通過在類型中嵌入其他類型或者結構體來實現

// WashingMachine 洗衣機 type WashingMachine interface {wash()dry() }// 甩干器 type dryer struct{}// 實現WashingMachine接口的dry()方法 func (d dryer) dry() {fmt.Println("甩一甩") }// 海爾洗衣機 type haier struct {dryer //嵌入甩干器 }// 實現WashingMachine接口的wash()方法 func (h haier) wash() {fmt.Println("洗刷刷") } func main() {var x WashingMachinevar a haierx = ax.dry() //輸出:甩一甩}

3.使用接口的原因

上面的代碼中定義了貓和狗,然后它們都會叫,你會發現main函數中明顯有重復的代碼,如果我們后續再加上豬、青蛙等動物的話,我們的代碼還會一直重復下去。那我們能不能把它們當成“能叫的動物”來處理呢?
像類似的例子在我們編程過程中會經常遇到:
比如一個網上商城可能使用支付寶、微信、銀聯等方式去在線支付,我們能不能把它們當成“支付方式”來處理呢?
比如三角形,四邊形,圓形都能計算周長和面積,我們能不能把它們當成“圖形”來處理呢?
比如銷售、行政、程序員都能計算月薪,我們能不能把他們當成“員工”來處理呢?
Go語言中為了解決類似上面的問題,就設計了接口這個概念。接口區別于我們之前所有的具體類型,接口是一種抽象的類型。當你看到一個接口類型的值時,你不知道它是什么,唯一知道的是通過它的方法能做什么

type Cat struct{}func (c Cat) Say() string { return "喵喵喵" }type Dog struct{}func (d Dog) Say() string { return "汪汪汪" }func main() {c := Cat{}fmt.Println("貓:", c.Say())d := Dog{}fmt.Println("狗:", d.Say()) }

4.接口的方法錯誤定義

package mainimport ("fmt" )type Phone interface {call() } //會編譯報錯 func (i Phone) call() {fmt.Println("q23erg") } func main() {}

5.空接口

5.1空結構體占用16字節

type demo interface { }func main() {var a demofmt.Println(unsafe.Sizeof(a)) //輸出16var b interface{}fmt.Println(unsafe.Sizeof(b)) //輸出16var c complex64fmt.Println(unsafe.Sizeof(c)) //輸出8 }

5.2類型斷言

5.1定義

5.2v,ok=x.(Y)應用

func main() {var x interface{}x = "pprof.cn"v, ok := x.(string)if ok {fmt.Println(v)} else {fmt.Println("類型斷言失敗")}//輸出:pprof.cn } func main() {var x interface{}x = "pprof.cn"v, ok := x.(bool)if ok {fmt.Println(v)} else {fmt.Println("類型斷言失敗")}//輸出:類型斷言失敗 }

5.3type switch 語句介紹


5.4結合switch語句

func justifyType(x interface{}) {switch v := x.(type) {case string:fmt.Printf("x is a string,value is %v\n", v)case int:fmt.Printf("x is a int is %v\n", v)case bool:fmt.Printf("x is a bool is %v\n", v)default:fmt.Println("unsupport type!")} } func main() {var x interface{}x = "pprof.cn"justifyType(x) //輸出:x is a string,value is pprof.cn }

總結

以上是生活随笔為你收集整理的GoLang之接口interface的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。