亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

golang: 詳解interface和nil

2019-11-11 04:49:37
字體:
來源:轉載
供稿:網友

golang的nil在概念上和其它語言的null、None、nil、NULL一樣,都指代零值或空值。nil是預先說明的標識符,也即通常意義上的關鍵字。在golang中,nil只能賦值給指針、channel、func、interface、map或slice類型的變量。如果未遵循這個規則,則會引發panic。對此官方有明確的說明:http://pkg.golang.org/pkg/builtin/#Type

golang中的interface類似于java的interface、php的interface或C++的純虛基類。接口就是一個協議,規定了一組成員。這個沒什么好說的,本文不打算對宏觀上的接口概念和基于接口的范式編程做剖析。golang語言的接口有其獨到之處:只要類型T的公開方法完全滿足接口I的要求,就可以把類型T的對象用在需要接口I的地方。這種做法的學名叫做Structural Typing,有人也把它看作是一種靜態的Duck Typing。所謂類型T的公開方法完全滿足接口I的要求,也即是類型T實現了接口I所規定的一組成員。

在底層,interface作為兩個成員來實現,一個類型和一個值。對此官方也有文檔說明:http://golang.org/doc/go_faq.html#nil_error,如果您不習慣看英文,這里有一篇柴大的翻譯:Go中error類型的nil值和nil 。

接下來通過編寫測試代碼和gdb來看看interface倒底是什么。會用到反射,如果您不太了解golang的反射是什么,這里有刑星翻譯自官方博客的一篇文章:反射的規則,原文在:laws-of-reflection。

[cpp] view plain copy 在CODE上查看代碼片package main     import (      "fmt"      "reflect"  )     func main() {      var val interface{} = int64(58)      fmt.$ cd $GOPATH/src/interface_test  $ go build -gcflags "-N -l"  $ gdb interface_test  

接下來說說interface類型的值和nil的比較問題。這是個比較經典的問題,也算是golang的一個坑。

接下來看看代碼

[cpp] view plain copy 在CODE上查看代碼片package main  import (      "fmt"  )  func main() {      var val interface{} = nil      if val == nil {          fmt.Println("val is nil")      } else {          fmt.Println("val is not nil")      }  }  變量val是interface類型,它的底層結構必然是(type,%20data)。由于nil是untyped(無類型),而又將nil賦值給了變量val,所以val實際上存儲的是(nil,%20nil)。因此很容易就知道val和nil的相等比較是為true的。

[cpp] view%20plain copy $ cd $GOPATH/src/interface_test  $ go build  $ ./interface_test  val is nil  

對于將任何其它有意義的值類型賦值給val,都導致val持有一個有效的類型和數據。也就是說變量val的底層結構肯定不為(nil,%20nil),因此它和nil的相等比較總是為false。

上面的討論都是在圍繞值類型來進行的。在繼續討論之前,讓我們來看一種特例:(*interface{})(nil)。將nil轉成interface類型的指針,其實得到的結果僅僅是空接口類型指針并且它指向無效的地址。注意是空接口類型指針而不是空指針,這兩者的區別蠻大的,學過C的童鞋都知道空指針是什么概念。

關于(*interface{})(nil)還有一些要注意的地方。這里僅僅是拿(*interface{})(nil)來舉例,對于(*int)(nil)、(*byte)(nil)等等來說是一樣的。上面的代碼定義了接口指針類型變量val,它指向無效的地址(0x0),因此val持有無效的數據。但它是有類型的(*interface{})。所以val的底層結構應該是:(*interface{},%20nil)。有時候您會看到(*interface{})(nil)的應用,比如var%20ptrIface%20=%20(*interface{})(nil),如果您接下來將ptrIface指向其它類型的指針,將通不過編譯。或者您這樣賦值:*ptrIface%20=%20123,那樣的話編譯是通過了,但在運行時還是會panic的,這是因為ptrIface指向的是無效的內存地址。其實聲明類似ptrIface這樣的變量,是因為使用者只是關心指針的類型,而忽略它存儲的值是什么。還是以例子來說明:

[cpp] view%20plain copy package main  import (      "fmt"  )  func main() {      var val interface{} = (*interface{})(nil)      // val = (*int)(nil)      if val == nil {          fmt.Println("val is nil")      } else {          fmt.Println("val is not nil")  很顯然,無論該指針的值是什么:(*interface{},%20nil),這樣的接口值總是非nil的,即使在該指針的內部為nil。

[cpp] view%20plain copy $ cd $GOPATH/src/interface_test  $ go build  $ ./interface_test  val is not nil  interface類型的變量和nil的相等比較出現最多的地方應該是error接口類型的值與nil的比較。有時候您想自定義一個返回錯誤的函數來做這個事,可能會寫出以下代碼:

[cpp] view%20plain copy package main     import (      "fmt"  )     type data struct{}     func (this *data) Error() string { return "" }     func test() error {      var p *data = nil      return p  }     func main() {      var e error = test()      if e == nil {          fmt.Println("e is nil")      } else {          fmt.Println("e is not nil")      }  }  但是很可惜,以上代碼是有問題的。

[cpp] view%20plain copy $ cd $GOPATH/src/interface_test  $ go build  $ ./interface_test  e is not nil  

我們可以來分析一下。error是一個接口類型,test方法中返回的指針p雖然數據是nil,但是由于它被返回成包裝的error類型,也即它是有類型的。所以它的底層結構應該是(*data,%20nil),很明顯它是非nil的??梢源蛴∮^察下底層結構數據:

[cpp] view%20plain copy package main     import (      "fmt"      "unsafe"  )     type data struct{}     func (this *data) Error() string { return "" }     func test() error {      var p *data = nil      return p  }     func main() {      var e error = test()         d := (*struct {          itab uintptr          data uintptr      })(unsafe.Pointer(&e))         fmt.Println(d)  }    $ cd $GOPATH/src/interface_test  $ go build  $ ./interface_test  &{3078907912 0}  正確的做法應該是:

[cpp] view%20plain copy 派生到我的代碼片package main     import (      "fmt"  )     type data struct{}     func (this *data) Error() string { return "" }     func bad() bool {      return true  }     func test() error {      var p *data = nil      if bad() {          return p      }      return nil  }     func main() {      var e error = test()      if e == nil {          fmt.Println("e is nil")      } else {          fmt.Println("e is not nil")      }  }  


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品日韩视频在线观看| 国产成人精品亚洲精品| 亚洲成人国产精品| 日韩国产高清污视频在线观看| 2019最新中文字幕| 亚洲18私人小影院| 欧美亚洲午夜视频在线观看| 国产精品91在线| 尤物yw午夜国产精品视频| 一区二区三区 在线观看视| 91干在线观看| 日韩一区二区三区在线播放| 国产91精品网站| 亚洲男人天堂网| 92国产精品久久久久首页| 欧美日韩午夜剧场| 亚洲性线免费观看视频成熟| 精品国产自在精品国产浪潮| 亚洲福利在线视频| 欧美巨大黑人极品精男| 亚洲欧美国产精品| 成人444kkkk在线观看| 欧美激情视频给我| 国产精品爽黄69天堂a| 97超视频免费观看| 日韩精品免费一线在线观看| 国产精品777| 国产香蕉精品视频一区二区三区| 亚洲国产一区自拍| 国产在线观看一区二区三区| 国产一区在线播放| 亚洲精品成人久久电影| 日韩禁在线播放| 国产精品久久久久免费a∨大胸| 色婷婷**av毛片一区| 欧美视频在线观看免费| 国产视频精品免费播放| 青青a在线精品免费观看| 97国产suv精品一区二区62| 国产精品9999| 欧美激情精品久久久久久蜜臀| 成人性生交大片免费观看嘿嘿视频| 精品视频www| 国产福利精品在线| 亚洲国产又黄又爽女人高潮的| 最近中文字幕mv在线一区二区三区四区| 国产亚洲精品久久久| 欧美第一黄网免费网站| 日韩电影中文字幕| 韩国国内大量揄拍精品视频| 欧美肥婆姓交大片| 精品国产31久久久久久| xxxxx成人.com| 91在线色戒在线| 欧美人与物videos| 国产欧美日韩中文字幕在线| 在线成人中文字幕| 国产精品美腿一区在线看| 久久精品国亚洲| 精品无人国产偷自产在线| 午夜精品在线观看| 日韩大片在线观看视频| 亚洲欧美日韩精品久久| 日本aⅴ大伊香蕉精品视频| 一本一道久久a久久精品逆3p| 久久精品国产免费观看| 色婷婷久久一区二区| 亚洲图片在线综合| 日韩美女主播视频| 久操成人在线视频| 最近2019免费中文字幕视频三| 性色av香蕉一区二区| 国内精品久久久久影院优| 久久人人爽人人爽人人片av高清| 亚洲影院色在线观看免费| 亚洲成人免费网站| 国产亚洲欧美日韩精品| 97在线观看视频国产| 中文字幕av一区中文字幕天堂| 国产欧亚日韩视频| 中文字幕日韩欧美精品在线观看| 亚洲a∨日韩av高清在线观看| 国精产品一区一区三区有限在线| 亚洲美女黄色片| 亚洲视频一区二区| 欧美午夜影院在线视频| 国产精品露脸自拍| 2019中文在线观看| 亚洲一区二区三区四区在线播放| 精品国内产的精品视频在线观看| 久久综合伊人77777尤物| 亚洲国产精品va在线看黑人动漫| 国产精品电影网站| 欧美另类69精品久久久久9999| 日韩电影在线观看中文字幕| 最新的欧美黄色| 色樱桃影院亚洲精品影院| 成人性教育视频在线观看| 欧美激情影音先锋| 成人免费视频在线观看超级碰| 欧美成人午夜视频| 亚洲综合最新在线| 久久久影视精品| 欧美精品在线免费播放| 国产经典一区二区| 538国产精品视频一区二区| 91免费精品国偷自产在线| 最新国产成人av网站网址麻豆| 国产精品一区二区三区免费视频| 欧美中文字幕视频在线观看| 欧美插天视频在线播放| 一区二区成人av| 动漫精品一区二区| 久久精品国产免费观看| 久久亚洲精品国产亚洲老地址| 久久久久久高潮国产精品视| 久久久久久国产| 国产视频久久久| 亚洲日韩欧美视频一区| 一区二区亚洲欧洲国产日韩| 亚洲欧美制服丝袜| 亚洲最大成人在线| 久久精品在线视频| 成人久久久久爱| 日韩精品视频三区| 国产999精品视频| 成人美女av在线直播| 日韩国产欧美精品在线| 日韩精品中文字幕久久臀| 岛国av在线不卡| 欧美一区二区视频97| 亚洲免费精彩视频| 欧美午夜精品久久久久久浪潮| 亚洲国产成人一区| 日韩在线观看免费网站| 久久精品免费播放| 久久伊人免费视频| 日韩经典中文字幕在线观看| 色婷婷**av毛片一区| 神马国产精品影院av| 亚洲最新视频在线| 久久视频中文字幕| 亚洲无线码在线一区观看| 日韩成人在线电影网| 97人人模人人爽人人喊中文字| 91高潮精品免费porn| 性欧美亚洲xxxx乳在线观看| 欧美乱大交做爰xxxⅹ性3| 91视频九色网站| 国内精品中文字幕| 国产精品久久久久久亚洲影视| 91超碰中文字幕久久精品| 日韩精品视频在线观看网址| 欧美电影在线免费观看网站| 久久91亚洲精品中文字幕奶水| 亚洲电影免费观看| 国产aⅴ夜夜欢一区二区三区| 77777少妇光屁股久久一区| 国产91ⅴ在线精品免费观看| 成人国产亚洲精品a区天堂华泰| 国产精品入口免费视频一| 亚洲欧洲午夜一线一品| 色偷偷av一区二区三区乱| 自拍偷拍亚洲欧美|