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類型
接口類型向普通類型的轉換稱為類型斷言(運行期確定)-------摘自《Go語言的類型轉換和類型斷言》 http://my.oschina.net/chai2010/blog/161418
其它參考:http://blog.csdn.net/jonnyhsu/article/details/41148753
所以前面代碼中,將echoArray()做如下修改即可:
func echoArray(a interface{}){
b,_:=a.([]int)//通過斷言實現類型轉換
for _,v:=range b{
fmt.Print(v," ")
}
fmt.Println()
return
}
-----------------------15/11/8更新---------------------------------
注意:在使用斷言時最好用
b,ok:=a.([]int)
if ok{
...
}
的形式,這樣能根據ok的值判斷斷言是否成功。
因為斷言失敗在編譯階段不會報錯,所以很可能出現斷言失敗導致運行錯誤,而你卻遲遲找不到原因(親身經歷)。
-----------------------15/11/21更新-----------------------------
注意:不同類型變量的運算必須進行顯式的類型轉換,否者結果可能出錯,如下例:
func main() {
var a uint8 = 8
c := a * 32
fmt.Println(a*32, c)
fmt.Println(reflect.TypeOf(c))
d := a * 31
fmt.Println(a*31, d)
fmt.Println(reflect.TypeOf(d))
return
}
/* 輸出:
** 0 0
** uint8
** 248 248
** uint8
*/
a*32的結果為0,原因是uint8可以表示的最大值為255( 1111 1111 ),而a*32的值為256(1 0000 0000 ),舍棄溢出的高位后即為0
也就是說,go不自動根據a*32的結果為其賦予合適的類型,而是根據a的類型強制其為uint8,所以最終c 和 d 的類型也為uint8。
總結:
1.interface{}使得我們可以向函數傳遞任意類型的變量;
2.斷言解決在使用interface{}的情況下,空接口類型向普通類型轉換的類型轉換問題;
3.普通類型之間的轉換最好使用顯式的類型轉換,否者很可能導致嚴重的錯誤。
4.以上是我個人的理解,希望各位沒有被我繞糊塗
-----------------------------------------------------
* 本文是根據自身經驗所作,難免存在不合理之處。
