C語言中文網 目錄
首頁 > Go語言教程 > Go語言接口 閱讀:2,441

Go語言空接口類型(interface{})

空接口是接口類型的特殊形式,空接口沒有任何方法,因此任何類型都無須實現空接口。從實現的角度看,任何值都滿足這個接口的需求。因此空接口類型可以保存任何值,也可以從空接口中取出原值。

提示

空接口類型類似于 C#Java 語言中的 Object、C語言中的 void*、C++ 中的 std::any。在泛型和模板出現前,空接口是一種非常靈活的數據抽象保存和使用的方法。

空接口的內部實現保存了對象的類型和指針。使用空接口保存一個數據的過程會比直接用數據對應類型的變量保存稍慢。因此在開發中,應在需要的地方使用空接口,而不是在所有地方使用空接口。

將值保存到空接口

空接口的賦值如下:
var any interface{}

any = 1
fmt.Println(any)

any = "hello"
fmt.Println(any)

any = false
fmt.Println(any)
代碼輸出如下:
1
hello
false

對代碼的說明:
  • 第 1 行,聲明 any 為 interface{} 類型的變量。
  • 第 3 行,為 any 賦值一個整型 1。
  • 第 4 行,打印 any 的值,提供給 fmt.Println 的類型依然是 interface{}。
  • 第 6 行,為 any 賦值一個字符串 hello。此時 any 內部保存了一個字符串。但類型依然是 interface{}。
  • 第 9 行,賦值布爾值。

從空接口獲取值

保存到空接口的值,如果直接取出指定類型的值時,會發生編譯錯誤,代碼如下:
// 聲明a變量, 類型int, 初始值為1
var a int = 1

// 聲明i變量, 類型為interface{}, 初始值為a, 此時i的值變為1
var i interface{} = a

// 聲明b變量, 嘗試賦值i
var b int = i
第8行代碼編譯報錯:

cannot use i (type interface {}) as type int in assignment: need type assertion

編譯器告訴我們,不能將i變量視為int類型賦值給b。

在代碼第 15 行中,將 a 的值賦值給 i 時,雖然 i 在賦值完成后的內部值為 int,但 i 還是一個 interface{} 類型的變量。類似于無論集裝箱裝的是茶葉還是煙草,集裝箱依然是金屬做的,不會因為所裝物的類型改變而改變。

為了讓第 8 行的操作能夠完成,編譯器提示我們得使用 type assertion,意思就是類型斷言。

使用類型斷言修改第 8 行代碼如下:
var b int = i.(int)
修改后,代碼可以編譯通過,并且 b 可以獲得 i 變量保存的 a 變量的值:1。

空接口的值比較

空接口在保存不同的值后,可以和其他變量值一樣使用==進行比較操作。空接口的比較有以下幾種特性。

1) 類型不同的空接口間的比較結果不相同

保存有類型不同的值的空接口進行比較時,Go 語言會優先比較值的類型。因此類型不同,比較結果也是不相同的,代碼如下:
// a保存整型
var a interface{} = 100

// b保存字符串
var b interface{} = "hi"

// 兩個空接口不相等
fmt.Println(a == b)
代碼輸出如下:
false

2) 不能比較空接口中的動態值

當接口中保存有動態類型的值時,運行時將觸發錯誤,代碼如下:
// c保存包含10的整型切片
var c interface{} = []int{10}

// d保存包含20的整型切片
var d interface{} = []int{20}

// 這里會發生崩潰
fmt.Println(c == d)
代碼運行到第8行時發生崩潰:

panic: runtime error: comparing uncomparable type []int

這是一個運行時錯誤,提示 []int 是不可比較的類型。下表中列舉出了類型及比較的幾種情況。

類型的可比較性
類  型 說  明
map 宕機錯誤,不可比較
切片([]T) 宕機錯誤,不可比較
通道(channel) 可比較,必須由同一個 make 生成,也就是同一個通道才會是 true,否則為 false
數組([容量]T) 可比較,編譯期知道兩個數組是否一致
結構體 可比較,可以逐個比較結構體的值
函數 可比較

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo