go中空接口的具體使用
接口-空接口
1. 什么是空接口?
空接口是特殊形式的接口類型,普通的接口都有方法,而空接口沒有定義任何方法口,也因此,我們可以說所有類型都至少實現(xiàn)了空接口。
type empty_iface interface { }
每一個接口都包含兩個屬性,一個是值,一個是類型。
而對于空接口來說,這兩者都是 nil,可以使用 fmt 來驗證一下
package main import "fmt" type empty_interface interface{ } func main() { var e empty_interface fmt.Println(e) fmt.Printf("type: %T, value: %v", e, e) }T, value: %v", i, i) }
輸出如下
<nil>
type: <nil>, value: <nil>
2. 如何使用空接口?
第一,
通常我們會直接使用 interface{}
作為類型聲明一個實例,而這個實例可以承載任意類型的值。
package main import ( "fmt" ) func main() { // 聲明一個空接口實例 var i interface{} // 存 int 沒有問題 i = 1 fmt.Printf("type: %T, value: %v\n", i, i) // 存字符串也沒有問題 i = "hello" fmt.Printf("type: %T, value: %v\n", i, i) // 存布爾值也沒有問題 i = false fmt.Printf("type: %T, value: %v\n", i, i) }
輸出結果:
type: int, value: 1
type: string, value: hello
type: bool, value: false
第二,
如果想讓你的函數(shù)可以接收任意類型的值 ,也可以使用空接口
接收一個任意類型的值 示例
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) }
輸出結果:
type: int, value: 10
type: string, value: hello
type: bool, value: true
接收任意個任意類型的值 示例
package main import ( "fmt" ) func myfunc(ifaces ...interface{}){ for _,iface := range ifaces{ fmt.Printf("type: %T, value: %v\n", iface, iface) } } func main() { a := 10 b := "hello" c := true myfunc(a, b, c) }
輸出結果:
type: int, value: 10
type: string, value: hello
type: bool, value: true
第三,
你也定義一個可以接收任意類型的 array、slice、map、strcut,例如這邊定義一個切片
package main import "fmt" func main() { any := make([]interface{}, 5) any[0] = 11 any[1] = "hello world" any[2] = []int{11, 22, 33, 44} for i, value := range any { fmt.Printf("arr[%d]:\nType: %T, Value: %v\n", i,value, value) } }
輸出結果:
arr[0]:
Type: int, Value: 11
arr[1]:
Type: string, Value: hello world
arr[2]:
Type: []int, Value: [11 22 33 44]
arr[3]:
Type: <nil>, Value: <nil>
arr[4]:
Type: <nil>, Value: <nil>
3. 空接口幾個要注意的坑
坑1:
空接口可以承載任意值,但不代表任意類型就可以承接空接口類型的值
從實現(xiàn)的角度看,任何類型的值都滿足空接口。因此空接口類型可以保存任何值,也可以從空接口中取出原值。
但要是你把一個空接口類型的對象,再賦值給一個固定類型(比如 int, string等類型)的對象賦值,是會報錯的。
package main func main() { // 聲明a變量, 類型int, 初始值為1 var a int = 1 // 聲明i變量, 類型為interface{}, 初始值為a, 此時i的值變?yōu)? var i interface{} = a // 聲明b變量, 嘗試賦值i var b int = i }
這個報錯,它就好比可以放進行禮箱的東西,肯定能放到集裝箱里,但是反過來,能放到集裝箱的東西就不一定能放到行禮箱了,在 Go 里就直接禁止了這種反向操作。(聲明:底層原理肯定還另有其因,但對于新手來說,這樣解釋也許會容易理解一些。)
面向對象\空接口\demo06.go:11:17: cannot use i (variable of type interface{}) as int value in variable declaration: need type assertion
坑2:
當空接口承載數(shù)組和切片后,該對象(就是空接口對象)無法再進行切片
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) }
執(zhí)行會報錯。
面向對象\空接口\demo07.go:11:10: invalid operation: cannot slice i (variable of type interface{})
坑3:
當你使用空接口來接收任意類型的參數(shù)時,它的靜態(tài)類型是 interface{},但動態(tài)類型(是 int,string 還是其他類型)我們并不知道,因此需要使用類型斷言。
package main import ( "fmt" ) func myfunc(i interface{}) { switch x:=i.(type) { case int: fmt.Printf("參數(shù)的值為:%v,參數(shù)的類型是 int\n",x) case string: fmt.Printf("參數(shù)的值為:%v,參數(shù)的類型是 string\n",x) } } func main() { a := 10 b := "hello" myfunc(a) myfunc(b) }
輸出如下
參數(shù)的值為:10,參數(shù)的類型是 int
參數(shù)的值為:hello,參數(shù)的類型是 string
到此這篇關于go中空接口的具體使用的文章就介紹到這了,更多相關go 空接口內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Go語言中的空值(nil)與零值(zerovalue)區(qū)別詳解
在Go語言中,空值(nil)和零值(zero value)是兩個不同的概念,它們在語義、使用場景以及實際的編程實踐中有著明顯的區(qū)別,理解這兩者的差異對于編寫清晰、健壯的Go代碼至關重要,需要的朋友可以參考下2024-06-06深入理解Golang中的Protocol Buffers及其應用
本篇文章將深入探討 Go 語言中使用 Protobuf 的基礎知識、常見應用以及最佳實踐,希望能幫大家了解如何在項目中高效利用 Protobuf2024-11-11go語言實戰(zhàn)之實現(xiàn)比特幣地址校驗步驟
這篇文章主要介紹了go語言實戰(zhàn)之實現(xiàn)比特幣地址校驗步驟,利用生產的隨機數(shù)采用橢圓加密算法生成公鑰,具體步驟實例代碼請參考下本文2021-05-05Go使用database/sql操作數(shù)據(jù)庫的教程指南
Go?語言中,有一個名為database/sql的標準庫,提供了統(tǒng)一的編程接口,使開發(fā)人員能夠以一種通用的方式與各種關系型數(shù)據(jù)庫進行交互,本文就來和大家講講它的具體操作吧2023-06-06