最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go?interface?接口的最佳實(shí)踐經(jīng)驗(yàn)分享

 更新時(shí)間:2022年04月15日 10:13:42   作者:西京刀客  
go?的接口在go的編程里面用的十分頻繁,尤其是空接口的使用,因?yàn)橛辛私涌?,才使得Go語言變得異常的強(qiáng)大,今天給大家介紹下Go?interface?接口的最佳實(shí)踐經(jīng)驗(yàn)分享,感興趣的朋友一起看看吧

Go語言-Go 接口的最佳實(shí)踐

原文連接:https://blog.boot.dev/golang/golang-interfaces/

Go 中的接口允許我們暫時(shí)將不同的類型視為相同的數(shù)據(jù)類型,因?yàn)檫@兩種類型實(shí)現(xiàn)相同的行為。它們是Go程序員工具箱的核心,并且經(jīng)常被新的Go開發(fā)人員不正確地使用,導(dǎo)致代碼不可讀且經(jīng)常有錯(cuò)誤。

什么是Golang中的interface

In Go, an interface is a custom type that other types are able to implement, which gives Go developers a powerful way to use abstraction. Interfaces are named collections of method signatures, and when other types implement all the required methods, they implicitly implement the interface.

在 Go 中,接口是其他類型可以實(shí)現(xiàn)的自定義類型,這為 Go 開發(fā)人員提供了使用抽象的強(qiáng)大方式。接口是方法簽名的集合,當(dāng)其他類型實(shí)現(xiàn)所有需要的方法時(shí),它們隱式地實(shí)現(xiàn)了接口。

例如,Go 中的errors是接口,標(biāo)準(zhǔn)error接口很簡(jiǎn)單,一個(gè)類型要被認(rèn)為是error,所需要做的就是定義一個(gè) Error ()方法,該方法不接受任何參數(shù),并返回一個(gè)字符串。

type error interface {
    Error() string
}

錯(cuò)誤error的簡(jiǎn)單性使得編寫日志和metrics 實(shí)現(xiàn)更加容易。讓我們定義一個(gè)表示網(wǎng)絡(luò)問題的結(jié)構(gòu)體:

type networkProblem struct {
	message string
	code    int
}

然后我們可以定義一個(gè) Error ()方法:

func (np networkProblem) Error() string {
	return fmt.Sprintf("network error! message: %s, code: %v", np.message, np.code)
}

現(xiàn)在,我們可以在接受錯(cuò)誤的任何地方使用 networkProblem struct 的實(shí)例。

func handleErr(err error) {
	fmt.Println(err.Error())
}
np := networkProblem{
	message: "we received a problem",
	code:    404,
}
handleErr(np)
// prints "network error! message: we received a problem, code: 404"

編寫接口的最佳實(shí)踐

編寫干凈的接口是困難的。坦率地說,任何時(shí)候你都在處理代碼中的抽象,如果你不小心的話,簡(jiǎn)單可以很快變成復(fù)雜。讓我們回顧一下保持interfaces整潔的一些經(jīng)驗(yàn)法則。

  • Keep interfaces small 保持interfaces足夠小
  • Interfaces should have no knowledge of satisfying types 接口應(yīng)該沒有令人滿意的類型的知識(shí)
  • Interfaces are not classes 接口不是類

1. 保持interfaces足夠小

If there is only one piece of advice that you take away from this article, make it this: keep interfaces small! Interfaces are meant to define the minimal behavior necessary to accurately represent an idea or concept.

如果您從本文中只得到了一條建議,那就是: 保持接口小一些!接口意味著定義精確表示一個(gè)想法或概念所需的最小行為。

下面是一個(gè)大型接口的標(biāo)準(zhǔn) HTTP package的例子,它是定義最小行為的一個(gè)很好的例子:

type File interface {
    io.Closer
    io.Reader
    io.Seeker
    Readdir(count int) ([]os.FileInfo, error)
    Stat() (os.FileInfo, error)
}

Any type that satisfies the interface’s behaviors can be considered by the HTTP package as a File. This is convenient because the HTTP package doesn’t need to know if it’s dealing with a file on disk, a network buffer, or a simple []byte.

任何滿足接口行為的類型都可以被 HTTP package 視為File。這很方便,因?yàn)?HTTP package 不需要知道它是在處理磁盤上的文件、還是網(wǎng)絡(luò)緩沖區(qū)或是[]byte

2. Interfaces Should Have No Knowledge of Satisfying Types

An interface should define what is necessary for other types to classify as a member of that interface. They shouldn’t be aware of any types that happen to satisfy the interface at design time.

接口應(yīng)該定義其他類型作為該接口的成員所必需的內(nèi)容。他們不應(yīng)該知道在設(shè)計(jì)時(shí)為了滿足接口而發(fā)生的任何類型。

例如,假設(shè)我們正在構(gòu)建一個(gè)接口來描述定義汽車所必需的構(gòu)成元素。

type car interface {
	Color() string
	Speed() int
	IsFiretruck() bool
}

Color() and Speed() make perfect sense, they are methods confined to the scope of a car. IsFiretruck() is an anti-pattern. We are forcing all cars to declare whether or not they are firetrucks. In order for this pattern to make any amount of sense, we would need a whole list of possible subtypes. IsPickup(), IsSedan(), IsTank()… where does it end??

Color()Speed()非常合理,它們是限制在汽車范圍內(nèi)的方法。IsFiretruck ()是一個(gè)反模式。我們正在強(qiáng)制所有的汽車申報(bào)它們是否是消防車。為了使這個(gè)模式具有任何意義,我們需要一個(gè)可能的子類型的完整列表。IsPickup () ,IsSedan () ,IsTank () … 它在哪里結(jié)束?

Instead, the developer should have relied on the native functionality of type assertion to derive the underlying type when given an instance of the car interface. Or, if a sub-interface is needed, it can be defined as:

相反,當(dāng)給定汽車接口的實(shí)例時(shí),開發(fā)人員應(yīng)該依賴于類型斷言的原生功能來派生基礎(chǔ)類型?;蛘?,如果需要子接口,可以將其定義為:

type firetruck interface {
	car
	HoseLength() int
}

它繼承了汽車所需的方法,并增加了一個(gè)額外的所需方法,使汽車一輛消防車。

3. 接口不是類

  • Interfaces are not classes, they are slimmer. 接口不是類,它們更小
  • Interfaces don’t have constructors or deconstructors that require that data is created or destroyed. 接口沒有要求創(chuàng)建或銷毀數(shù)據(jù)的構(gòu)造函數(shù)或解構(gòu)函數(shù)
  • Interfaces aren’t hierarchical by nature, though there is syntactic sugar to create interfaces that happen to be supersets of other interfaces. 接口本質(zhì)上并不具有層次性,盡管在創(chuàng)建恰好是其他接口的超集的接口時(shí)存在語法糖
  • Interfaces define function signatures, but not underlying behavior. Making an interface often won’t 接口定義函數(shù)簽名,但不定義底層行為。制作interface通常不會(huì)在結(jié)構(gòu)方法方面不干擾您的代碼。例如,如果五種類型滿足錯(cuò)誤接口,那么它們都需要自己的版本的Error() function. 函數(shù)

有關(guān)接口的更多信息

空的接口

空接口沒有指定任何方法,因此 Go 中的每個(gè)類型都實(shí)現(xiàn)了空接口。

interface{}

It’s for this reason that developers sometimes use a map[string]interface{} to work with arbitrary JSON data, although I recommend using anonymous structs instead where possible.

出于這個(gè)原因,開發(fā)人員有時(shí)使用 map[string]interface{}來處理任意 JSON 數(shù)據(jù),盡管我推薦在可能的情況下使用匿名結(jié)構(gòu)。

Zero value of an interface

Interfaces can be nil, in fact, it’s their zero value. That’s why when we check for errors in Go, we’re always checking if err != nil, because err is an interface.

接口可以是 nil,事實(shí)上,這是它們的零值。這就是為什么當(dāng)我們?cè)?Go 中檢查錯(cuò)誤時(shí),我們總是檢查err != nil,因?yàn)?err 是一個(gè)接口。

指針上的接口

It’s a common “gotcha” in Go to implement a method on a pointer type and expect the underlying type to implement the interface, it doesn’t work like that.

在 Go 中,在指針類型上實(shí)現(xiàn)一個(gè)方法并期望底層類型實(shí)現(xiàn)接口是一個(gè)常見的“明白了”,它不是這樣工作的。

type rectangle interface {
    height() int
    width() int
}

type square struct {
    length int
}

func (sq *square) width() int {
    return sq.length
}

func (sq *square) height() int {
    return sq.length
}

Though you may expect it to, in this example the square type does not implement the rectangle interface. The *square type does. If I wanted the square type to implement the rectangle interface I would just need to remove the pointer receivers.

雖然您可能希望這樣做,但是在這個(gè)示例中,正方形類型不實(shí)現(xiàn)矩形接口。它使用的是*square。如果我想讓正方形類型實(shí)現(xiàn)矩形接口,我只需要?jiǎng)h除指針接收器。

type rectangle interface {
    height() int
    width() int
}

type square struct {
    length int
}

func (sq square) width() int {
    return sq.length
}

func (sq square) height() int {
    return sq.length
}

到此這篇關(guān)于Go interface 接口的最佳實(shí)踐的文章就介紹到這了,更多相關(guān)Go interface 接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang 一次性定時(shí)器Timer用法及實(shí)現(xiàn)原理詳解

    golang 一次性定時(shí)器Timer用法及實(shí)現(xiàn)原理詳解

    這篇文章主要為大家介紹了golang 一次性定時(shí)器Timer用法及實(shí)現(xiàn)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Go語言服務(wù)器開發(fā)之簡(jiǎn)易TCP客戶端與服務(wù)端實(shí)現(xiàn)方法

    Go語言服務(wù)器開發(fā)之簡(jiǎn)易TCP客戶端與服務(wù)端實(shí)現(xiàn)方法

    這篇文章主要介紹了Go語言服務(wù)器開發(fā)之簡(jiǎn)易TCP客戶端與服務(wù)端實(shí)現(xiàn)方法,實(shí)例分析了基于Go語言實(shí)現(xiàn)的簡(jiǎn)易服務(wù)器的TCP客戶端與服務(wù)器端實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-02-02
  • golang channel讀取數(shù)據(jù)的幾種情況

    golang channel讀取數(shù)據(jù)的幾種情況

    本文主要介紹了golang channel讀取數(shù)據(jù)的幾種情況,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Golang為什么占用那么多的虛擬內(nèi)存原理解析

    Golang為什么占用那么多的虛擬內(nèi)存原理解析

    這篇文章主要介紹了Golang為什么占用那么多的虛擬內(nèi)存原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • 淺談golang 中time.After釋放的問題

    淺談golang 中time.After釋放的問題

    這篇文章主要介紹了淺談golang 中time.After釋放的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go工具鏈之go tool cover使用方法和示例詳解

    Go工具鏈之go tool cover使用方法和示例詳解

    go tool cover是Go工具鏈中的一個(gè)命令,作用是分析測(cè)試用例的代碼覆蓋率,本文將對(duì)go tool cover 作用,使用方法和使用場(chǎng)景作一個(gè)簡(jiǎn)單的介紹,感興趣的同學(xué)可以參考閱讀一下
    2023-07-07
  • golang gin框架獲取參數(shù)的操作

    golang gin框架獲取參數(shù)的操作

    這篇文章主要介紹了golang gin框架獲取參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 使用Go?goroutine實(shí)現(xiàn)并發(fā)的Clock服務(wù)

    使用Go?goroutine實(shí)現(xiàn)并發(fā)的Clock服務(wù)

    這篇文章主要為大家詳細(xì)介紹了如何使用Go?goroutine實(shí)現(xiàn)并發(fā)的Clock服務(wù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-06-06
  • 淺談go 協(xié)程的使用陷阱

    淺談go 協(xié)程的使用陷阱

    這篇文章主要介紹了淺談go 協(xié)程的使用陷阱,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言編程實(shí)現(xiàn)支持六種級(jí)別的日志庫?

    Go語言編程實(shí)現(xiàn)支持六種級(jí)別的日志庫?

    這篇文章主要為大家介紹了使用Golang編寫一個(gè)支持六種級(jí)別的日志庫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05

最新評(píng)論

盱眙县| 保山市| 长海县| 大荔县| 米脂县| 新昌县| 华宁县| 静宁县| 平谷区| 平南县| 长顺县| 唐海县| 大埔区| 惠水县| 神农架林区| 乳山市| 辉县市| 枞阳县| 城步| 扶沟县| 乳山市| 台中市| 确山县| 革吉县| 望奎县| 菏泽市| 西和县| 垦利县| 遂溪县| 襄汾县| 平泉县| 广平县| 喀喇| 河南省| 宝应县| 隆德县| 安多县| 白山市| 九龙县| 化隆| 潜江市|