Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use (*struct) as (*interface) in field value

Tags:

interface

go

I have the following code:

// eventloop.go
type Object interface {
    ActivateSlot(name string, parameters vector.Vector);
}



// main.go
import loop "./eventloop"

// ...

const slotname = "printer"

type printer struct {
    slot loop.Slot;
}

func (p *printer) Init() {
    p.slot = loop.Slot{slotname, p}; // offending line
}

func (p *printer) ActivateSlot(name string, parameters vector.Vector) {
    fmt.Println("Slot called: ", name); 
}

When I try to compile, I get the following error:

jurily@jurily ~/workspace/go $ ./build.sh
main.go:23: cannot use p (type *printer) as type *eventloop.Object in field value

If I comment the offending line out, it compiles and runs fine. What's happening here? What am I missing?

like image 688
György Andrasek Avatar asked Nov 30 '09 04:11

György Andrasek


1 Answers

Update: This code compiles fine here (all in the same package):

type Object interface {
    ActivateSlot(name string, parameters vector.Vector);
}
type Slot struct {
  name string;
  stuff Object;
}

const slotname = "printer"
type printer struct {
    slot Slot;
}
func (p *printer) Init() {
    p.slot = Slot{slotname, p}; // offending line
}
func (p *printer) ActivateSlot(name string, parameters vector.Vector) {
    fmt.Println("Slot called: ", name);
}

It seems that what you are missing is that *printer is of type Object, and you are trying to assign it to a field of type *Object, which is a different type.

In most cases you would write it like above - without pointers to interface types - but if you have to, you can make it compile like this:

type Slot struct {
  name string;
  stuff *Object;
}
func (p *printer) Init() {
     var o Object = p;
    p.slot = Slot{slotname, &o}; // offending line
}

So p is an Object, you need to take the address of p to match the *Object specification.

like image 159
j-g-faustus Avatar answered Nov 15 '22 03:11

j-g-faustus