日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Go面試題:Gointerface的一個(gè)“坑”及原理分析

 [[387825]]

創(chuàng)新互聯(lián)建站于2013年開(kāi)始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元建甌做網(wǎng)站,已為上家服務(wù),為建甌各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220

本文轉(zhuǎn)載自微信公眾號(hào)「腦子進(jìn)煎魚(yú)了」,作者陳煎魚(yú)。轉(zhuǎn)載本文請(qǐng)聯(lián)系腦子進(jìn)煎魚(yú)了公眾號(hào)。

大家好,我是煎魚(yú)。

前幾天在讀者交流群里看到一位小伙伴,針對(duì) interface 的使用有了比較大的疑惑。

無(wú)獨(dú)有偶,我也在網(wǎng)上看到有小伙伴在 Go 面試的時(shí)候被問(wèn)到了:

來(lái)自網(wǎng)上博客的截圖

今天特意分享出來(lái)讓大家避開(kāi)這個(gè)坑。

例子一

第一個(gè)例子,如下代碼:

 
 
 
 
  1. func main() { 
  2.     var v interface{} 
  3.     v = (*int)(nil) 
  4.     fmt.Println(v == nil) 

你覺(jué)得輸出結(jié)果是什么呢?

答案是:

 
 
 
 
  1. false 

為什么不是 true。明明都已經(jīng)強(qiáng)行置為 nil 了。是不是 Go 編譯器有問(wèn)題?

例子二

第二個(gè)例子,如下代碼:

 
 
 
 
  1. func main() { 
  2.     var data *byte 
  3.     var in interface{} 
  4.  
  5.     fmt.Println(data, data == nil) 
  6.     fmt.Println(in, in == nil) 
  7.  
  8.     in = data 
  9.     fmt.Println(in, in == nil) 

你覺(jué)得輸出結(jié)果是什么呢?

答案是:

 
 
 
 
  1.  true 
  2.  true 
  3.  false 

這可就更奇怪了,為什么剛剛聲明出來(lái)的 data 和 in 變量,確實(shí)是輸出結(jié)果是 nil,判斷結(jié)果也是 true。

怎么把變量 data 一賦予給變量 in,世界就變了?輸出結(jié)果依然是 nil,但判定卻變成了 false。

和上面的第一個(gè)例子結(jié)果類似,真是神奇。

原因

interface 判斷與想象中不一樣的根本原因是,interface 并不是一個(gè)指針類型,雖然他看起來(lái)很像,以至于誤導(dǎo)了不少人。

我們鉆下去 interface,interface 共有兩類數(shù)據(jù)結(jié)構(gòu):

  • runtime.eface 結(jié)構(gòu)體:表示不包含任何方法的空接口,也稱為 empty interface。
  • runtime.iface 結(jié)構(gòu)體:表示包含方法的接口。

看看這兩者相應(yīng)的底層數(shù)據(jù)結(jié)構(gòu):

 
 
 
 
  1. type eface struct { 
  2.     _type *_type 
  3.     data  unsafe.Pointer 
  4.  
  5. type iface struct { 
  6.     tab  *itab 
  7.     data unsafe.Pointer 

你會(huì)發(fā)現(xiàn) interface 不是單純的值,而是分為類型和值。

所以傳統(tǒng)認(rèn)知的此 nil 并非彼 nil,必須得類型和值同時(shí)都為 nil 的情況下,interface 的 nil 判斷才會(huì)為 true。

解決辦法

與其說(shuō)是解決方法,不如說(shuō)是委婉的破局之道。在不改變類型的情況下,方法之一是利用反射(reflect),如下代碼:

 
 
 
 
  1. func main() { 
  2.     var data *byte 
  3.     var in interface{} 
  4.  
  5.     in = data 
  6.     fmt.Println(IsNil(in)) 
  7.  
  8. func IsNil(i interface{}) bool { 
  9.     vi := reflect.ValueOf(i) 
  10.     if vi.Kind() == reflect.Ptr { 
  11.         return vi.IsNil() 
  12.     } 
  13.     return false 

利用反射來(lái)做 nil 的值判斷,在反射中會(huì)有針對(duì) interface 類型的特殊處理,最終輸出結(jié)果是:true,達(dá)到效果。

其他方法的話,就是改變?cè)械某绦蜻壿?,例如?/p>

  • 對(duì)值進(jìn)行 nil 判斷,再返回給 interface 設(shè)置。
  • 返回具體的值類型,而不是返回 interface。

總結(jié)

Go interface 是 Go 語(yǔ)言中最常用的類型之一,大家用慣了 if err != nil 就很容易順手就踩進(jìn)去了。

 


分享名稱:Go面試題:Gointerface的一個(gè)“坑”及原理分析
文章源于:http://www.5511xx.com/article/cciioso.html