go:interface{}、斷言與類型轉換

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/161418ui

 

其它參考http://blog.csdn.net/jonnyhsu/article/details/41148753spa

 

因此前面代碼中,將echoArray()作以下修改便可:.net

func echoArray(a interface{}){
    b,_:=a.([]int)//經過斷言實現類型轉換
  for _,v:=range b{
    fmt.Print(v," ")
  }
  fmt.Println()
  return
} 

-----------------------15/11/8更新---------------------------------blog

注意:在使用斷言時最好用 接口

b,ok:=a.([]int)
if ok{
    ...
}

的形式,這樣能根據ok的值判斷斷言是否成功。get

由於斷言失敗在編譯階段不會報錯,因此極可能出現斷言失敗致使運行錯誤,而你卻遲遲找不到緣由(親身經歷)。  編譯

-----------------------15/11/21更新----------------------------- class

注意:不一樣類型變量的運算必須進行顯式的類型轉換,否者結果可能出錯,以下例:

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.以上是我我的的理解,但願各位沒有被我繞糊塗  

-----------------------------------------------------

* 本文是根據自身經驗所做,不免存在不合理之處。

* 以上內容爲做者原創,轉載請註明出處。
-----------------------------------------------------
相關文章
相關標籤/搜索