2017-01-11 54 views
2

根據this question,golang將同時生成type-receiver methodpoint-receiver method,這意味着下面的代碼將正常工作,並且值會意外改變。Golang方法接收器

func (test *Test) modify() { 
    test.a++ 
} 

func main() { 
    test := Test{10} 
    fmt.Println(test) 
    test.modify() 
    fmt.Println(test) 
} 

我認爲這是可以接受的。但是當這與界面混合時,事情就會出錯。

type Modifiable interface { 
    modify() 
} 

type Test struct { 
    a int 
} 

func (test *Test) modify() { 
    test.a++ 
} 

func main() { 
    test := Test{10} 
    fmt.Println(test) 
    test.modify() 
    fmt.Println(test) 

    var a Modifiable 

    a = test 
} 

它說:

Test does not implement Modifiable (modify method has pointer receiver) 

爲什麼會出現這種情況?

golang實際上是如何處理方法調用的?

回答

1

當你說:

func (test *Test) modify() { 
    test.a++ 
} 

這意味着該接口Modifiable由又名指針類型*Test實施測試

凡爲

func (test Test) modify() { 
     test.a++ 
} 

意味着該接口由類型Test

結論是:類型和指向該類型的指針是2種不同的類型。

+0

但是'test'變量確實有一個名爲'modify'的方法,我可以通過'test.modify()'調用,爲什麼它說'Test不能實現可修改'? – KIDJourney

+0

因爲你在'* Test'上實現了接口而不是'Test'。 '修改'方法是爲'Test'而不是'Test'類型定義的。當你調用'test.modify'時,編譯器會自動傳遞'* Test',但是從接口實現的角度來看,你需要明確地使用'* Test' – Ankur

+0

所以給定鏈接的答案是錯誤的,'Test '沒有生成?編譯器真正做的是將指針傳遞給'pointer-method',而不是調用不存在的生成方法。 – KIDJourney

0

如果您想使用具有指針接收器的方法。這意味着你必須傳遞地址值。

這裏是例子:

package main 

import "fmt" 

type Modifiable interface { 
    modify() 
} 

type Test struct { 
    a int 
} 

func (test *Test) modify() { 
    test.a++ 
} 

func main() { 
    test := Test{10} 
    fmt.Println(test) 
    test.modify() 
    fmt.Println(test) 

    var a Modifiable 

    a = &test 
    a.modify() 
    fmt.Println(a) 
} 

總之,只要你創建的方法指針接收器的接口將接受地址值。