duanliexi1052
2017-08-05 21:12
浏览 36
已采纳

在Go中,我可以返回符合接口的结构但无法访问该接口吗?

I think the best way to explain this is by example, so here it is:

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)
}

This prints false. You can run and play with it: https://play.golang.org/p/A_2k_ku_Q2

In my real case the struct Hello and the interfaces for Greeter and Greeting are in different packages that do not import each other and I wanted to keep it that way. I'm perhaps missing some understanding of interfaces in Go but after reading so much about it I still can't put my finger on it. Would you guys have any pointers for me? Maybe another approach for the problem? Thanks!

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douchai7891 2017-08-06 01:50
    已采纳

    As stated in the comments, problem here is once your interface has this signature:

    type Greeter interface {
        Greet() Greeting
    }
    

    The any valid implementation must use exactly Greeting as the return type.

    But, as the documentation shows, you don't need to give the interface a name:

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

    In order to be able to implement what you need, you might declare the interface directly in the return value, without giving it a name.

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

    Then your Greet() function for Hello can do this:

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

    Find here a modified playground showing the working example:

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

    已采纳该答案
    评论
    解决 无用
    打赏 举报