简体   繁体   中英

In Go can I return a struct that meets an interface without access to that interface?

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!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM