2017-08-05 21 views
3

我想解釋這是通過示例的最好方式,所以在這裏它是:在Go中,我可以返回一個符合接口而不訪問該接口的結構嗎?

package main 

import (
    "fmt" 
) 

// Greeter greets with a Greeting. 
type Greeter interface { 
    Greet() Greeting 
} 

// A Greeting has a string representation. 
type Greeting interface { 
    String() string 
} 

type Hello struct {} 

// Hello greets by returning itself... 
func (h *Hello) Greet() *Hello { 
    return h 
} 

// ...because Hello also has a string representation. 
func (h *Hello) String() string { 
    return "Hello" 
} 

// But Go says Hello doesn't implement Greeter. 
func main() { 
    var g interface{} = &Hello{} 
    g, ok := g.(Greeter) 
    fmt.Println(ok) 
} 

這將打印false。您可以運行並使用它:https://play.golang.org/p/A_2k_ku_Q2

在我的現實情況下,結構Hello和接口GreeterGreeting不同的包不導入對方,我想保持這種方式。我可能錯過了對Go中接口的一些理解,但在閱讀了很多關於它之後,我仍然無法理解它。你們對我有任何指點嗎?也許是另一種解決問題的方法?謝謝!

+4

沒有的'返回類型問候'必須完全是'問候'的類型,以適應'Greeter'界面? – user2357112

+0

@ user2357112據我所知是的。但正如我上面提到的,在我的情況下,接口和結構是在不同的包中。因此,在我定義方法'Greet()* Hello'的地方,我無法訪問該接口。 –

+0

方法定義必須完美匹配要滿足的接口。即使你輸入了Mystring string,然後試圖從String()方法中返回一個Mystring,它也不會滿足Greeting的接口。 – RayfenWindspear

回答

8

正如評論所說,這裏的問題是,一旦你的接口有此簽名:

type Greeter interface { 
    Greet() Greeting 
} 

的任何有效的實現必須使用完全相同Greeting作爲返回類型。

但是,作爲文檔顯示,你不需要給該接口的名稱:

https://golang.org/ref/spec#Interface_types

爲了能夠實現你需要什麼,你可能會直接申報界面返回值,而不給它一個名字。

// Greeter greets with anything that has a String() method 
type Greeter interface { 
    Greet() interface{ String() string } 
} 

然後你Greet()功能Hello可以這樣做:

// Hello greets by returning itself... 
func (h *Hello) Greet() interface{ String() string } { 
    return h 
} 

在這裏找到展示工作例如改變的遊樂場:

https://play.golang.org/p/HteA_9jFd4

相關問題