什么是空介面?
空介面是特殊形式的介面型別,普通的介面都有方法,而空介面沒有定義任何方法,也因此,我們可以說所有型別都至少實作了空介面,
type empty_iface interface {
}
每一個介面都包含兩個屬性,一個是值,一個是型別,
而對于空介面來說,這兩者都是nil,可以用fmt來驗證一下,
package main
import "fmt"
func main() {
var i interface{}
fmt.Printf("type:T%,value:v%",i,i)
}
輸出如下:
type: <nil>,value:<nil>
如何使用空介面?
-
通常我們會直接用
interface{}作為型別宣告一個實體,而這個實體可以承載任何型別的值,package main import "fmt" func main() { // 宣告一個空介面實體 var i interface{} // 存int沒有問題 i = 1 fmt.Println(i) // 存字串沒有問題 i = "hello" fmt.Println(i) // 存布林值沒有問題 i = true fmt.Println(i) } -
如果想讓你的函式可以接收任意型別的值,也可以使用空介面
接收
一個任意型別的值 示例package main import "fmt" func myfunc(iface interface{}) { fmt.Println(iface) } func main() { a := 10 b := "hello" c := true myfunc(a) myfunc(b) myfunc(c) }接收
任意個任意型別的值 示例package main import "fmt" func myfunc(ifaces ...interface{}) { for _,iface := range ifaces { fmt.Println(iface) } } func main() { a := 10 b := "hellow" c := true myfunc(a,b,c) } -
你也可以定義一個可以接收任意型別的array、slice、map、struct,例如這邊定義一個切片
package main import "fmt" func main() { any := make([]interface{},5) any[0] = 11 any[1] = "hello world" any[2] = []int{11,22,33} for _,value := range any { fmt.Println(value) } }
空介面幾個要注意的坑
-
空介面可以承載任意值,但并不代表任意型別就可以承接空介面型別的值
從實作的角度看,任何型別的值都滿足空介面,因此空介面型別可以保存任何值,也可以從空介面中取出原值,
但要是把一個空介面型別的物件,再賦值給一個固定型別(比如int,string等型別)的物件賦值,是會報錯的,
package main func main() { // 宣告變數a,型別int,初始值為1 var a int = 1 // 宣告i變數,型別為interface,初始值為a,此時i的值變為1 var i interface{} = a // 宣告b變數,嘗試賦值i var b int = i }Go里直接禁止了這種反向操作,報錯如下:
./main.go:16:6: cannot use i (type interface {}) as type int in assignment: need type assertion -
當空介面承載陣列和切片后,該物件無法再進行切片
package main import "fmt" func main() { sli := []int{2,3,5,7,11,13} var i interface{} i = sli g := i[1:3] fmt.Println(g) }執行會報錯
./main.go:16:8: cannot slice i (type interface {}) -
當使用空介面來接收任意型別的引數時,它的靜態型別時interface{},但動態型別是(int,string還是其他型別)我們并不知道,因此需要使用型別斷言,
package main import "fmt" func myfunc(i interface{}) { switch i.(type) { case int: fmt.Println("引數型別是 int") case string: fmt.Println("引數型別是 string") } } func main() { a := 10 b := "hello" myfunc(a) myfunc(b) }輸出如下
引數型別是 int 引數型別是 string
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/1906.html
標籤:Go
上一篇:golang nsq示例使用介紹
