首頁 > 後端開發 > Golang > 主體

go語言可以開發介面嗎

青灯夜游
發布: 2022-12-16 17:17:28
原創
5468 人瀏覽過

go語言可以開發介面。 go語言中介面是一組方法的簽名,它是go語言中重要的組成部分,介面做的事情就好像是定義一個規範或協議,各個實作方只要按照協議實作即可。 go語言中使用interface關鍵字來定義接口,語法“type 接口類型名 interface{方法名1( 參數列表1 ) 返回值列表1 方法名2( 參數列表2 ) 返回值列表2…}”。

go語言可以開發介面嗎

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

介面對我們來說應該是一個比較熟悉的概念,在各種開發語言中運用都非常的廣泛,對於像我們比較熟悉java的程式設計師來說對於介面就更加的親切,下面我們來看下在go語言中介面是怎麼用,以及介面在日常開發中所扮演的角色。

概念

go語言中介面是一組方法的簽名,它是go語言中重要的組成部分,介面做的事情就好像是定義一個規範或協議,各個實現方只要依照協議實現即可。

介面是一種類型

介面類型是對其他類型行為的抽象和概括,不關心具體的實作細節,這種抽象的方式可以讓我們的函數變的更加靈活。

介面定義

type 接口类型名 interface{
    方法名1( 参数列表1 ) 返回值列表1
    方法名2( 参数列表2 ) 返回值列表2
    …
}
登入後複製

在go語言中我們使用interface關鍵字來定義介面。

介面實作條件

如果一個任意型別T的方法集為一個介面類型的方法集的超集,則我們說類型T實作了該介面。

介面的實作在go語言中是隱式的,也就說兩個類型之間的實作關係不需要在程式碼中體現出來,GO語言中沒有類似java中implements的關鍵字,Go編譯器將自動在需要的時候檢查兩個類型之間的實作關係。接口定義後,需要實作接口,呼叫方才能正確編譯通過並使用接口。

介面的實作需要遵循兩個規則才能讓介面可用:

1、介面的方法與實作介面的類型方法格式一致在類型中加入與介面簽章一致的方法就可以實作該方法。簽名包括方法中的名稱、參數清單、傳回參數清單。也就是說,只要實作介面類型中的方法的名稱、參數清單、傳回參數清單中的任一項與介面要實作的方法不一致,那麼介面的這個方法就不會被實作。

package main

import "fmt"

type Phone interface {
	Call()
	SendMessage()
}

type HuaWei struct {
	Name  string
	Price float64
}

func (h *HuaWei) Call() {
	fmt.Printf("%s:可以打电话",h.Name)
}

func (h *HuaWei) SendMessage() {
	fmt.Printf("%s:可以发送短信",h.Name)
}

func main() {

	h := new(HuaWei)
	h.Name="华为"
	var phone Phone
	phone = h
	phone.SendMessage()
}
登入後複製

當型別無法實作介面時,編譯器會報錯:

##        a.函數名稱不一致所造成的報錯

##        b.實作函數的方法簽章不一致所導致的報錯

2、介面中所有方法都實作當一個介面中有多個方法時,只有這些方法都實作了,介面才能被正確編譯並使用 

func (h *Xiaomi) Call() {
	fmt.Printf("%s:可以打电话",h.Name)
}

func main() {
	h := new(Xiaomi)
	h.Name="小米"
	var phone Phone
	phone = h
	phone.SendMessage()
}
登入後複製

go語言可以開發介面嗎當小米類型只是實作介面中的一個方法的時候,我們在使用的時候,編譯錯誤。 

類型與介面的關係

一個類型實作多個介面

一個型別可以實作多個接口,而介面之間彼此獨立,不知道對方的實作。

例如,狗既可以動,可以叫

package main

import "fmt"

type Move interface {
	move()
}
type Say interface {
	say()
}
type Dog struct {
	Name string
}

func (d *Dog) move()  {
	fmt.Printf("%s会动\n", d.Name)
}
func (d *Dog) say()  {
	fmt.Printf("%s会叫汪汪汪\n", d.Name)
}

func main() {
	var m Move
	var s  Say
	d:=&Dog{
		Name: "旺财",
	}
	m = d
	s=d
	m.move()
	s.say()
}
登入後複製

多個類型實作同一個介面 Go語言中不同的類型還可以實現同一接口首先我們定義一個Mover接口,它要求必須有一個move方法。

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)
}
登入後複製

這時候我們在程式碼中就可以把狗和汽車當成一個會動的物體來處理了,不再需要關注它們具體是什麼,只需要呼叫它們的move方法就可以了。

func main() {
        var x Mover
        var a = dog{name: "旺财"}
        var b = car{brand: "保时捷"}
        x = a
        x.move()
        x = b
        x.move()
    }
登入後複製

空接口

 空接口:interface{},不包含任何方法,正因為如此,任何類型都實現了空接口,所以空接口可以存儲任意類型的資料。

fmt

 套件下的 Print 系列函數,其參數大多是空介面類型,也可以說支援任意型別<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">func Print(a ...interface{}) (n int, err error) func Println(format string, a ...interface{}) (n int, err error) func Println(a ...interface{}) (n int, err error)</pre><div class="contentsignin">登入後複製</div></div>空介面作為map的值

// 空接口作为map值
    var studentInfo = make(map[string]interface{})
    studentInfo["name"] = "李白"
    studentInfo["age"] = 18
    studentInfo["married"] = false
    fmt.Println(studentInfo)
登入後複製

類型推斷

空介面可以儲存任意類型的值,那我們要如何取得其儲存的具體資料呢?

介面值

一個介面的值(簡稱介面值)是由一個特定類型和具體類型的值兩部分組成的。

這兩部分分別稱為介面的動態類型和動態值。

想要判斷空介面中的值這個時候就可以使用型別斷言,其語法格式:

x.(T)
登入後複製

其中:

    x:表示類型為interface{}的變數
  • T:表示斷言x可能是的型別。

该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。

func main() {
    var x interface{}
    x = "ms的go教程"
    v, ok := x.(string)
    if ok {
        fmt.Println(v)
    } else {
        fmt.Println("类型断言失败")
    }
}
登入後複製

 上面的示例中如果要断言多次就需要写多个if判断,这个时候我们可以使用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!")
    }
}
登入後複製

因为空接口可以存储任意类型值的特点,所以空接口在Go语言中的使用十分广泛。

总结

关于接口需要注意的是,只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行时损耗。

【相关推荐:Go视频教程编程教学

以上是go語言可以開發介面嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板