Go學習筆記:Go的指針、interface

最近在使用Go的過程當中,遇到了和指針相關的一些問題,通過整理,發現和我最開始理解的指針還不太同樣。函數

問題一:在設計cache的時候,須要用到萬能類型interface來裝各類各樣的鍵值對,有時候有些參數根據須要得使用指針類型,剛開始會這樣寫測試

func test(a *interface{}){
   //do something here ...
}

會發現不管我傳什麼參數都會提示:this

cannot use *mytype as type *interface設計

這個問題與下面實際上是同一個問題。。。指針

問題二:有這麼一個需求,定義了一個接口A,在另外一個方法中,我想要設置一個參數是A的實現類型,由於這裏會涉及到數據的修改,所以確定是須要傳一個指針。所以,想固然的寫出了下面的代碼code

type myinterface interface{
	print()
}
func test(value *myinterface){
	//someting to do ...
}

剛開始以爲沒有問題,可是!在調用test的時候遇到了問題。接口

type mystruct struct {
	i int
}
//實現接口
func (this *mystruct) print(){
	fmt.Println(this.i)
	this.i=1
}
func main(){
m := &mystruct{0}
test(m)//錯誤
test(*m)//錯誤
}

*mystruct是實現了myinterface接口的,我但願test接收的是一個指針類型,所以傳*mystruct類型的數據。提示:Cannot use 'm' (type *mystruct) as type *myinterfaceit

說的很明確,沒法將*mystruct類型的數據賦值給*myinterface。經過查找各類資料,發如今go語言中,接口自己就是引用類型,換句話說,接口類型自己就是一個指針。對於個人需求,其實test的參數只要是myinterface就能夠了,只須要在傳值的時候,傳*mystruct類型(也只能傳*mystruct類型)class

使用下面的代碼測試一下test

//一個用於測試的接口
type myinterface interface{
	print()
}

//*mystruct現了myinterface接口
type mystruct struct {
	i int
}

type mystruct2 struct {
	i int
}

/**
測試一下map類型的指針問題
 */
func main() {
	//測試*mystruct實現效果
	m := &mystruct{0}
	fmt.Printf("address in main is %p\n", m)
	method1(*m)//method1的參數是mystruct類型
	m.print()//m的值並無受到影響
	method2(m)//method2的參數是接口類型
	m.print()//m的值被修改了
	//測試mystruct2實現效果
	fmt.Println("##########")
	m2 := &mystruct2{i:0}
	fmt.Printf("initial address is %p\n",m2)
	method3(*m2)
	m2.print()
	method2(m2)
	m2.print()
}

func method1(m mystruct) {
	fmt.Printf("address in method1 is %p\n", &m)
	m.print()
}

func method2(m myinterface){
	fmt.Printf("address in method2 is %p\n",m)
	m.print()
}

func method3(m mystruct2){
	fmt.Printf("address in method3 is %p\n",&m)
	m.print()
}

func (this *mystruct) print(){
	fmt.Println(this.i)
	this.i=1
}

func (this mystruct2) print(){
	fmt.Println(this.i)
	this.i=2
}

運行結果以下:

address in main is 0xc42001c090
address in method1 is 0xc42001c098
0
0
address in method2 is 0xc42001c090
1
1
##########
initial address is 0xc42001c0b0
address in method3 is 0xc42001c0b8
0
0
address in method2 is 0xc42001c0b0
0
0

能夠看到,使用method2的時候,地址與main函數中的地址是同樣的,也就是說,當參數是myinterface的時候,傳的是一個引用類型。

另外,mystruct2不管使用哪一種方式都沒有改變main函數中的值,這個是由於mystruct2的print函數。

func (this mystruct2) print()

這種聲明實際上是

func print(this mystruct2)

能夠看出,在print函數中傳的是值,而非地址,所以不會影響到外部函數。

在這個過程當中看到過一位大神說的一句:永遠不要使用指向interface的指針,這個是沒有意義的

相關文章
相關標籤/搜索