首頁 > 軟體

一文帶你瞭解Go語言中介面的使用

2022-12-05 14:01:00

介面

Go 語言中,介面是一種抽象的型別,是一組方法的集合。介面存在的目的是定義規範,而規範的細節由其他物件去實現。我們來看一個例子:

import "fmt"

type Person struct {
    Name string
}

func main() {
    person := Person{Name: "cmy"}
    fmt.Println(person) // {cmy}
}

上述程式碼定義了結構體 Personmain 函數建立了此結構體的變數 person,然後通過 fmt 包裡的 Println 函數列印這個結構體,列印結果為 {cmy}。在此基礎上,我們改造一下程式碼:

import "fmt"

type Person struct {
    Name string
}

func (p Person) String() string {
    return fmt.Sprintf("name: %s", p.Name)
}

func main() {
    person := Person{Name: "cmy"}
    fmt.Println(person) // name: cmy
}

新改造的程式碼裡為結構體 Person 新增一個結構體方法 String() string,方法的返回結果是對 name 進行格式化,我們再列印一下結構體,觀察結果發現是 String() 方法返回的值,而不是 {cmy}。 為什麼是這樣呢?這是因為 fmt.Println(T) 函數的實現細節裡,會對結構體進行判斷,如果結構體實現了 Stringer 介面,則會直接列印 String() 方法的返回值。以下是 Stringer 介面的程式碼:

type Stringer interface {
    String() string
}

結構體實現了這個介面,也就意味著遵守這個介面所定義的規範,fmt.Println(T) 函數發現結構體有這個規範,因此就會根據規範來列印資訊。基於 Stringer 介面,我們來看看介面的語法格式:

type XXX interface {
    // methods
}

1、type

介面的宣告,必須以 type 關鍵字開頭。

2、介面名

推薦駝峰式命名法,首字母大寫的方法名可以在包外存取,小寫的只能在包記憶體取。

3、interface

介面的標識。

4、介面體

大括號裡面宣告規範,也就是宣告方法,方法必須具有名字。

介面的實現

Go 語言裡,介面的實現不是基於介面,而是基於方法。如果一個自定義型別擁有了某個介面的所有方法,那麼這個自定義型別就實現這個介面。介面的實現在上述的例子中有所體現,Person 結構體定義了 String() string 方法,擁有了 Stringer 介面的所有方法,因此實現了 Stringer 介面。

一個自定義型別可以實現多個介面

type A interface {
        a()
}

type B interface {
        b()
}
type Person struct {
        Name string
}

func (p Person) a() {
}

func (p Person) b() {
}

A 介面宣告了 a 方法, B 介面宣告了 b 方法,Person 結構體定義了 ab 兩個方法,因此 Person 結構體實現了 AB 兩個介面。

介面型別變數

一旦介面被定義,它就可以用於宣告變數。

import "fmt"

type A interface {
}

func main() {
    var a A
    fmt.Println(a) // <nil>
}

如果只宣告介面變數,不初始化,變數的值預設為 nil,因為介面型別實際上是一個指標。若為介面賦初值,需要選擇一個合法的值,即被賦值的基礎類別必須實現這個介面。

空介面

Go 語言裡面可以認為所有型別實現了空介面,因為空介面沒有任何的方法。

import "fmt"

type EmptyInterface interface {
}

func main() {
    var a EmptyInterface = 1
    var b EmptyInterface = true
    var c EmptyInterface = "hello"
    var d EmptyInterface = 3.14
    var e EmptyInterface = 'c'
    fmt.Println(a, b, c, d, e) // 1 true hello 3.14 99
}

所有型別都實現空介面,因此空介面變數可以被賦初值為任意型別的值或變數。

型別斷言

Go 語言支援型別斷言操作,通過這個操作,可以還原介面變數的右值(被賦的初值)。型別斷言的語法形式通常為:

v, ok := a.(T)

如果斷言成功,那麼 v 的值為介面變數的值,ok 的值為 true;如果斷言失敗,v 的值為 T 型別的零值,ok 的值為 false

型別斷言變種 type switch

通過 type switch 的方式,可以判斷介面變數屬於哪種動態型別。

import "fmt"

type EmptyInterface interface {
}

func main() {
    var a EmptyInterface = 1
    switch a.(type) {
    case string:
	fmt.Println("a 的右值型別為 string")
    case int:
	fmt.Println("a 的右值型別為 int")
    case bool:
	fmt.Println("a 的右值型別為 bool")
    case float64:
	fmt.Println("a 的右值型別為 float64")
    }
}

小結

本文先是對介面的定義進行介紹,然後通過一個例子,瞭解了介面其中的一個應用場景和引出介面的語法格式以及實現的方法,然後介紹了空介面的特點和型別斷言,最後介紹了變種的型別斷言 type switch 的應用例子。

到此這篇關於一文帶你瞭解Go語言中介面的使用的文章就介紹到這了,更多相關Go語言介面內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com