On Thu, Jun 11, 2020 at 10:50 AM John Sturdy <jcg.stu...@gmail.com> wrote:
>
> I've defined an interface type, and a concrete type that I think implements 
> that interface, but when I use it in a list, I get an error from the compiler 
> that makes it look like it doesn't.
>
> Here's my interface type, in anything/anything.go:
>
>     package anything
>
>     import (
>             "fmt"
>     )
>
>     type AnyThing interface {
>             Textual() string
>             Numeric(name string) int
>     }
>
>     func OneCallee(thing AnyThing) {
>             fmt.Printf("textual result is %s and numeric result is %d\n", 
> thing.Textual(), thing.Numeric("default"))
>     }
>
>     func ListCallee(things []AnyThing) {
>             fmt.Printf("textual result is %s and numeric result is %d\n", 
> things[0].Textual(), things[0].Numeric("default"))
>     }
>
>
> and here's a concrete type that defines the methods required by the 
> interface, in particularthing/particularthing.go:
>
>     package particularthing
>
>     type ParticularThing struct {
>             Name string
>             Number int
>     }
>
>     func (n ParticularThing) Textual() string {
>             return n.Name
>     }
>
>     func (n ParticularThing) Numeric(name string) int {
>             return n.Number
>     }
>
> and here's the caller:
>
>     package main
>
>     import (
>             "example.com/user/scratch/anything"
>             "example.com/user/scratch/particularthing"
>     )
>
>     func main() {
>             onething := particularthing.ParticularThing{"this", 1}
>             anything.OneCallee(onething)
>             thinglist := make([]particularthing.ParticularThing, 1)
>             anything.ListCallee(thinglist)
>     }
>
> When I compile it, I get:
>
>     ./caller.go:12:21: cannot use thinglist (type 
> []particularthing.ParticularThing) as type []anything.AnyThing in argument to 
> anything.ListCallee
>
> Could some explain what the problem with this is?

An array of values implementing an interface cannot be used in place
of an array of those interfaces. Go's type system simply compares the
type required with the type provided, and []someInterface is not
[]someType. Note that the structure of the two objects passed to the
function is quite different. The function expects a []someInterface
where each element of the array is a pair containing the pointer to
the value and the type, but you are sending []someType where each
element is a value. So you have to convert:

intfList:=make([]AnyThing,0)
for _,x:=range thingList {
   intfList=append(intfList,x)
}
anything.ListCallee(intfList)

You can argue that the compiler can do this conversion. Such
potentially expensive operations are explicit in Go, which creates
some clutter but overall not a bad thing.



>
> I've attached a tarball of the files to make experimental changes easier.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/3abb649b-f134-4535-8832-18c8ca0a54ebo%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqo-6xZU%2BUkQBCTeyyjrrXoBFk5jTxHHTDmmF8dKMDRnjw%40mail.gmail.com.

Reply via email to