第一大部分
interface{} 可以接受任何類型的對象值
獲取interface{}隊形的數據類型,可以使用斷言,或者 switch type 來實現
// Assertion project main.go package main import ( "fmt" ) type Bag struct { Key string } type Bag2 struct { Key int } func main() { var b1 interface{} var b2 interface{} b1 = Bag{Key: "1"} b2 = Bag2{Key: 0} //獲取interface{}中存放的數據類型 //方法一: { //判斷是否是Bag類型 若不是則置0 b, ok := b1.(Bag) fmt.Println("Bag類型 :", ok, "數據", b) } { //判斷是否是Bag2類型 若不是則置0 b, ok := b2.(Bag2) fmt.Println("Bag2類型:", ok, "數據", b) } //方法二: switch v := b1.(type) { //v表示b1 接口轉換成Bag對象的值 case Bag: fmt.Println("b1.(type):", "Bag", v) case Bag2: fmt.Println("b1.(type):", "Bag2", v) default: fmt.Println("b1.(type):", "other", v) } }
斷言:一般使用於已知interface中的對象的數據類型,調用后自動將接口轉換成相應的對象,語法結構 接口對象(obj),存放的數據類型(string) ,v,ok := obj.(string),若是相應的對象ok則為真,v為相應對象及數據。
switch type: 已知或者未知的對象數據類型均可,b1.(type)必須配合switch來使用,不能單獨執行此語句。
switch v:= b1.(type){//b1為interface對象 ,v為相應對象及數據
case Bag: //類型為Bag時執行
fmt.Println(“b1.(type):”, “Bag”, v)
case Bag2://類型為Bag2時執行
fmt.Println(“b1.(type):”, “Bag2”, v)
default://類型為其他類型時執行
fmt.Println(“b1.(type):”, “other”, v)
}
第二部分 函數傳參時的任意類型的接口
interface{}可用於向函數傳遞任意類型的變量,但對於函數內部,該變量仍然為interface{}類型(空接口類型),
不清楚這點將可能導致錯誤。如以下代碼:
錯誤代碼:
package
main
import
"fmt"
/*
**用於輸出數組元素
*/
func
echoArray(a
interface
{}){
for
_,v:=
range
a{
fmt.Print(v,
" "
)
}
fmt.Println()
return
}
func
main(){
a:=[]int{2,1,3,5,4}
echoArray(a)
}
//以上代碼將會報錯,因為對於echoArray()而言,a是interface{}類型,而不是[]int類型
func echoArray(a interface{}){
b,ok:=a.([]int)//通過斷言實現類型轉換
if ok{
for _,v:=range b{
fmt.Print(v," ")
}
}
fmt.Println()
return
}
根據上面在函數內部轉化下的形式,這樣能根據ok的值判斷斷言是否成功。
因為斷言失敗在編譯階段不會報錯,所以很可能出現斷言失敗導致運行錯誤,而你卻遲遲找不到原因(親身經歷)。
1.interface{}使得我們可以向函數傳遞任意類型的變量;
2.斷言解決在使用interface{}的情況下,空接口類型向普通類型轉換的類型轉換問題;
3.普通類型之間的轉換最好使用顯式的類型轉換,否者很可能導致嚴重的錯誤。
4.以上是我個人的理解,希望各位沒有被我繞糊塗