婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Go之interface的具體使用

Go之interface的具體使用

熱門標簽:鄭州亮點科技用的什么外呼系統 汕頭小型外呼系統 黃岡人工智能電銷機器人哪個好 惠州電銷防封電話卡 阿里云ai電話機器人 浙江高頻外呼系統多少錢一個月 濱州自動電銷機器人排名 釘釘有地圖標注功能嗎 建造者2地圖標注

淺顯地了解了一下 Go,發現 Go 語法的設計非常簡潔,易于理解。正應了 Go 語言之父 Rob Pike 說的那句“Less is more”—— 大道至簡。

下面就具體的語法特性說說我自己的體會。

interface

概覽

與通常以類型層次與繼承為根基的面向對象設計(OOP)語言(如C++、Java)不同,Go 的核心思想就是組合(composition)。Go 進一步解耦了對象與操作,實現了真正的鴨子類型(Duck typing):一個對象如果能嘎嘎叫那就能當做鴨子,而不是像 C++ 或 Java 那樣需要類型系統去保證:一個對象先得是只鴨子,然后才能嘎嘎叫。

type Duck interface {
  Quack()
}

type Animal struct {
  name string
}

func (animal Animal) Quack() {
  fmt.Println(animal.name, ": Quack! Quack! Like a duck!")
}

func main() {
  unknownAnimal := Animal{name: "Unknown"}

  var equivalent Duck
  equivalent = unknownAnimal
  equivalent.Quack()
}

運行上面的代碼輸出:

Unknown : Quack! Quack! Like a duck!

下面用 Java 語言來實現:

interface Duck {
  void Quack();
}

class SomeAnimal implements Duck {
  String name;

  public SomeAnimal(String name) {
    this.name = name;
  }

  public void Quack() {
    System.out.println(name + ": Quack! Quack! I am a duck!");
  }
}

public class Test {
  public static void main(String []args){
    SomeAnimal unknownAnimal = new SomeAnimal("Unknown");
    Duck equivalent = unknownAnimal;
    equivalent.Quack();
  }
}

兩相比較就能看出:Go 將對象與對其的操作(方法或函數)解耦得更徹底。Go 并不需要一個對象通過類型系統來保證實現了某個接口(is a),而只需要這個對象實現了某個接口的方法即可(like a),而且類型聲明與方法聲明或實現也是松耦合的形式。如果稍微轉換一下方法的實現方式:

func (animal Animal) Quack() {
  fmt.Println(animal.name, ": Quack! Quack! Like a duck!")
}

為:

func Quack(animal Animal) {
  fmt.Println(animal.name, ": Quack! Quack! Like a duck!")
}

是不是就和普通方法并無二致了?

在深入淺出 Cocoa 之消息一文中我曾分析過 Objective C 的消息調用過程:

Bird * aBird = [[Bird alloc] init];
[aBird fly];

中對 fly 的調用,編譯器通過插入一些代碼,將之轉換為對方法具體實現 IMP 的調用,這個 IMP 是通過在 Bird 的類結構中的方法鏈表中查找名稱為 fly 的選擇子 SEL 對應的具體方法實現找到的,編譯器會將消息調用轉換為對消息函數 objc_msgSend的調用:

objc_msgSend(aBird, @selector(fly));

無論是 Objective C 的消息機制還是 Qt 中的 Signal/Slot 機制,可以說都是在嘗試將對象本身(數據)與對對象的操作(消息)解耦,但 Go 將這個工作在語言層面做得更加徹底,這樣不僅避免多重繼承問題,還體現出面向對象設計中最要緊的事情:對象間的消息傳遞。

實現

interface 實際上就是一個結構體,包含兩個成員。其中一個成員是指向具體數據的指針,另一個成員中包含了類型信息。空接口和帶方法的接口略有不同,下面分別是空接口和帶方法的接口是使用的數據結構:

struct Eface
{
  Type*  type;
  void*  data;
};
struct Iface
{
  Itab*  tab;
  void*  data;
};

struct Itab
{
  InterfaceType*  inter;
  Type*  type;
  Itab*  link;
  int32  bad;
  int32  unused;
  void  (*fun[])(void);
};

struct Type
{
  uintptr size;
  uint32 hash;
  uint8 _unused;
  uint8 align;
  uint8 fieldAlign;
  uint8 kind;
  Alg *alg;
  void *gc;
  String *string;
  UncommonType *x;
  Type *ptrto;
};

先看Eface,它是interface{}底層使用的數據結構。數據域中包含了一個void*指針,和一個類型結構體的指針。interface{}扮演的角色跟C語言中的void*是差不多的,Go中的任何對象都可以表示為interface{}。不同之處在于,interface{}中有類型信息,于是可以實現反射。

不同類型數據的類型信息結構體并不完全一致,Type是類型信息結構體中公共的部分,其中size描述類型的大小,UncommonType是指向一個函數指針的數組,收集了這個類型的具體實現的所有方法。

在reflect包中有個KindOf函數,返回一個interface{}的Type,其實該函數就是簡單的取Eface中的Type域。

Iface和Eface略有不同,它是帶方法的interface底層使用的數據結構。data域同樣是指向原始數據的,Itab中不僅存儲了Type信息,而且還多了一個方法表fun[]。一個Iface中的具體類型中實現的方法會被拷貝到Itab的fun數組中。

Type的UncommonType中有一個方法表,某個具體類型實現的所有方法都會被收集到這張表中。reflect包中的Method和MethodByName方法都是通過查詢這張表實現的。表中的每一項是一個Method,其數據結構如下:

struct Method
{
  String *name;
  String *pkgPath;
  Type  *mtyp;
  Type *typ;
  void (*ifn)(void);
  void (*tfn)(void);
};

Iface的Itab的InterfaceType中也有一張方法表,這張方法表中是接口所聲明的方法。其中每一項是一個IMethod,數據結構如下:

struct IMethod
{
  String *name;
  String *pkgPath;
  Type *type;
};

 跟上面的Method結構體對比可以發現,這里是只有聲明沒有實現的。

Iface中的Itab的func域也是一張方法表,這張表中的每一項就是一個函數指針,也就是只有實現沒有聲明。

類型轉換時的檢測就是看Type中的方法表是否包含了InterfaceType的方法表中的所有方法,并把Type方法表中的實現部分拷到Itab的func那張表中。

注意事項

一個interface在沒有進行初始化時,對應的值是nil。也就是說:

var v interface{}

此時v就是一個nil。在底層存儲上,它是一個空指針。

與之不同的情況

var obj *T
var v interface{}
v = obj

此時v是一個interface,它的值是nil,也就是說其data域為空,但它自身不為nil。

下面來看個例子就明白了:
Go語言中的error類型實際上是抽象了Error()方法的error接口:

type error interface {
  Error() string
}

有如下代碼:

type Error struct {
  errCode uint8
}

func (e *Error) Error() string {
  switch e.errCode {
  default:
    return "unknown error"
  }
}

func test_checkError() {
  var e *Error
  if e == nil {
    fmt.Println("e is nil")
  } else {
    fmt.Println("e is not nil")
  }

  var err error
  err = e

  if err == nil {
    fmt.Println("err is nil")
  } else {
    fmt.Println("err is not nil")
  }
}

運行test_checkError()輸出:

e is nil
err is not nil

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • 使用go的interface案例實現多態范式操作
  • Go語言實現類似c++中的多態功能實例
  • golang語言如何將interface轉為int, string,slice,struct等類型
  • golang基礎之Interface接口的使用
  • golang struct 實現 interface的方法
  • golang中struct和interface的基礎使用教程
  • Go語言中你不知道的Interface詳解
  • golang中interface接口的深度解析
  • 淺談Go語言多態的實現與interface使用

標簽:滄州 昭通 東營 阿壩 駐馬店 泰安 瀘州 晉中

巨人網絡通訊聲明:本文標題《Go之interface的具體使用》,本文關鍵詞  之,interface,的,具體,使用,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Go之interface的具體使用》相關的同類信息!
  • 本頁收集關于Go之interface的具體使用的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美片网站yy| 丝袜亚洲另类欧美综合| 一区二区三区在线视频免费观看| 奇米在线7777在线精品 | 国产99久久久国产精品免费看| 91国偷自产一区二区三区观看 | 成a人片国产精品| 成人欧美一区二区三区视频网页| 国产伦精品一区二区三区视频青涩| 337p日本欧洲亚洲大胆精品| 国产精品亚洲视频| 亚洲精品免费看| 日韩欧美另类在线| 国产夫妻精品视频| 亚洲精品国久久99热| 欧美日韩国产高清一区二区三区| 日本午夜精品一区二区三区电影| 日韩女优视频免费观看| 不卡大黄网站免费看| 天堂成人免费av电影一区| 精品免费视频一区二区| eeuss鲁片一区二区三区在线观看| 国产精品对白交换视频| 91精品国产一区二区| 国产成人精品三级| 亚洲第一会所有码转帖| 国产欧美日韩在线观看| 99久久精品免费| 强制捆绑调教一区二区| 一区二区三区小说| 久久精品在这里| 欧美性色欧美a在线播放| 韩国精品久久久| 亚洲国产日韩a在线播放| 久久精品一级爱片| 666欧美在线视频| 99久久99久久久精品齐齐| 久久99久久久久久久久久久| 亚洲精品视频在线| 午夜精品国产更新| 国产精品色哟哟网站| 日韩一区二区三区视频在线观看| 99久久伊人精品| 亚洲一区二区av电影| 久久网站最新地址| 在线看国产一区| 91蝌蚪porny成人天涯| 裸体歌舞表演一区二区| 亚洲va天堂va国产va久| 一区二区三区免费网站| 国产精品少妇自拍| 国产午夜精品一区二区| 精品国内片67194| 91.xcao| 日本久久精品电影| 在线亚洲免费视频| 91免费在线看| 欧美在线免费观看亚洲| 在线日韩一区二区| 色先锋资源久久综合| 色偷偷成人一区二区三区91| av在线综合网| 成人精品一区二区三区中文字幕| 国产一区二区三区免费观看| 日韩电影在线一区| 亚洲欧洲在线观看av| 久久新电视剧免费观看| 国产日产亚洲精品系列| 国产亚洲美州欧州综合国| 久久影视一区二区| 国产精品护士白丝一区av| 亚洲人成亚洲人成在线观看图片| 国产精品免费人成网站| 国产精品家庭影院| 依依成人精品视频| 亚洲国产成人porn| 日本欧美一区二区三区乱码| 蜜桃免费网站一区二区三区| 免费在线观看视频一区| 精品一区二区三区在线播放视频| 麻豆91在线看| 国产曰批免费观看久久久| 国产91丝袜在线观看| 成人av电影免费观看| 国产成人av福利| 色94色欧美sute亚洲线路一ni| 欧美日韩国产精品自在自线| 欧美一区二区私人影院日本| 精品国产免费人成电影在线观看四季| 欧美极品美女视频| 亚洲一区二区三区在线播放| 精品一区二区三区免费观看| 丁香六月综合激情| 18欧美亚洲精品| 亚洲在线视频网站| 狠狠色丁香久久婷婷综| 91丝袜美女网| 精品久久久久久无| 国产精品久久久久久久久果冻传媒| 亚洲色图欧美激情| 日本午夜精品视频在线观看 | 精品蜜桃在线看| 亚洲免费在线看| 久久 天天综合| 欧洲一区二区三区免费视频| 日韩免费视频一区| 一区二区三区四区亚洲| 蜜臀av亚洲一区中文字幕| 盗摄精品av一区二区三区| 在线成人高清不卡| 欧美日韩一级二级| 日本一区二区三区高清不卡| 亚洲精品日产精品乱码不卡| 成人黄色777网| 欧美日韩美少妇| 日韩一区中文字幕| 国精产品一区一区三区mba视频| 国产精品福利影院| 色婷婷综合久久久| 国产乱人伦偷精品视频不卡| voyeur盗摄精品| 一本色道**综合亚洲精品蜜桃冫| 欧美色老头old∨ideo| 日韩一区二区在线观看视频播放| 国产精品久久久久久福利一牛影视| 亚洲精品国产精华液| 国产成人av电影在线| 91精品国产综合久久香蕉的特点| 欧美va亚洲va国产综合| 免费高清成人在线| 宅男在线国产精品| 天堂av在线一区| 亚洲欧美激情在线| 亚洲福利视频导航| 日本一区二区久久| 亚洲视频免费在线观看| 精品一区二区三区免费| 在线不卡中文字幕| 午夜不卡av免费| 欧美亚洲动漫精品| 中国色在线观看另类| 成人黄色在线网站| 日韩一区二区麻豆国产| 午夜久久久影院| 一本大道久久a久久综合婷婷| 亚洲国产电影在线观看| 精品在线一区二区| 久久久综合九色合综国产精品| 一区二区三区加勒比av| 在线区一区二视频| 午夜av电影一区| 欧美一区二区三区四区高清| 日本不卡视频一二三区| 欧美另类一区二区三区| 精品一区二区三区在线播放| 欧美v国产在线一区二区三区| 国产精品久久久久天堂| 一色屋精品亚洲香蕉网站| 日本aⅴ免费视频一区二区三区| 欧美日韩国产免费一区二区| 日本成人在线不卡视频| 精品日产卡一卡二卡麻豆| 精品无码三级在线观看视频| 日韩精品中午字幕| 国产大陆精品国产| 欧美日韩日日骚| 久久99精品国产.久久久久| 99re成人在线| 亚洲国产成人高清精品| 国产99久久久国产精品潘金| 亚洲国产一区在线观看| 一本大道久久精品懂色aⅴ| 亚洲欧美aⅴ...| 欧美精品精品一区| 男男成人高潮片免费网站| 欧美韩日一区二区三区四区| 99久久婷婷国产综合精品电影 | 欧美三级视频在线播放| 婷婷丁香久久五月婷婷| 欧美丰满少妇xxxbbb| 国产综合久久久久久鬼色| 亚洲女性喷水在线观看一区| 精品久久久三级丝袜| 色噜噜夜夜夜综合网| 国产精品美女久久久久久久久| 色妞www精品视频| 国产精品护士白丝一区av| 精品久久久久久久久久久院品网 | www.99精品| 男人的天堂亚洲一区| 国产精品久久久久久久久图文区 | 99精品久久免费看蜜臀剧情介绍| 亚洲成人动漫在线观看| 中文字幕一区在线观看视频| 欧美精品一区二区不卡| 在线免费精品视频| 91在线观看视频| av男人天堂一区| 国产精品77777竹菊影视小说| 午夜精品视频一区|