-2

Hoping to have an interface that has attributes based on another interface. Is that possible?

Contrived Example:

type interface cheese {
  GetId() string
}

type interface cheeses {
  GetCheeses() []cheese
}

type CheeseStruct struct {
  GetId() string
}

type BowlOfCheeses struct {
  GetCheeses() []*CheeseStruct
}

func doSomething(thing cheeses) {
}

bowlOfCheeses := BowlOfCheeses{
  []*CheeseStruct{
    &CheeseStruct{}
  }
}

doSomething(bowlOfCheeses) # the match doesn't seem to be recognized
Drew
  • 2,583
  • 5
  • 36
  • 54
  • 2
    "embedded" interfaces absolutely work (e.g. https://pkg.go.dev/io#ReadWriter) . What have you tried? – JimB Oct 18 '21 at 17:13
  • 1
    Once you fix all the syntax issues, the problem here is simply that `BowlOfCheeses` doesn't implement `cheeses`. – Crowman Oct 18 '21 at 17:16
  • But can BowlOfCheese still have the concrete struct for it's type? Hoping to avoid having to change that @Crowman Feel free to ignore the syntax issues btw – Drew Oct 18 '21 at 17:21
  • `BowlOfCheeses` can certainly explicitly return a slice of its own type from `GetCheeses`, but as noted, it won't implement the `cheeses` interface if it does. – Crowman Oct 18 '21 at 17:23
  • Okay, to make sure I'm following, even though BowlOfCheeses is typed with a concretion that implements GetById() it won't work as it needs to be typed with the actual interface itself? @Crowman Thanks a ton for the help here btw – Drew Oct 18 '21 at 17:26
  • It doesn't, but thank you. I know about type assertions etc, but it just seems like there should be no need to change the return type of BowlOfCheeses GetCheeses function. Is there something I'm missing or is there a way to avoid having to change it's type? Typically I'd just go ahead and type it out as an interface as well, just in a position where it's not the most feasible thing to do – Drew Oct 18 '21 at 17:30
  • @Drew: `BowlOfCheeses` needs to provide the method(s) specified by the interface in order to implement that interface. Providing a different method that happens to share the same name isn't sufficient. – Crowman Oct 18 '21 at 17:31
  • So I guess where I'm confused is that not only does it have the same name, but `CheeseStruct` implements the `cheese` interface (as far as I can tell). Does that make sense? – Drew Oct 18 '21 at 17:34
  • Also, let me know if I'm off, but sounds like it must essentially have the exact typing and just a concretion that matches the interface associated w/ the GetCheeses array – Drew Oct 18 '21 at 17:36
  • Thanks, @mkopriva. Feel free to add that as an answer btw and I'll upvote it – Drew Oct 18 '21 at 17:46

1 Answers1

2

For a type T to implement an interface I, T's method set must contain all methods of I's method set, and the signatures of these methods must match verbatim, i.e. the name of the method, the input & output parameter count, order, and types must all match exactly.

GetCheeses() []cheese != GetCheeses() []*CheeseStruct

Also see: Why does Go not have covariant result types?

mkopriva
  • 35,176
  • 4
  • 57
  • 71