Cannot use as type in assignment in go

For anyone else pulling their hair out: check your imports.

Not sure when it started happening, but my Visual Studio Code + gopls setup will occasionally insert an import line that references my vendored dependencies path instead of the original import path. I usually won't catch this until I start polishing code for release, or an error like this one pops up.

In my case this caused two otherwise identical types to not compare equally. Once I fixed my imports this resolved the error.


The instance field within the Paxos struct is a map of integer keys to pointers to PaxosInstance structs.

When you call:

px.instance[seq] = px.InitializePaxosInstance(val)

You're attempting to assign a concrete (not pointer) PaxosInstance struct into an element of px.instance, which are pointers.

You can alleviate this by returning a pointer to a PaxosInstance in InitializePaxosInstance, like so:

func (px *Paxos) InitializePaxosInstance(val interface{}) *PaxosInstance {
    return &PaxosInstance{decided: false, value: val}
}

or you could modify the instance field within the Paxos struct to not be a map of pointers:

type Paxos struct {
    instance   map[int]PaxosInstance
}

Which option you choose is up to your use case.


Your map is expecting a pointer to a PaxosInstance (*PaxosInstance), but you are passing a struct value to it. Change your Initialize function to return a pointer.

func (px *Paxos) InitializePaxosInstance(val interface{}) *PaxosInstance {
    return &PaxosInstance {decided:false, value: val}
}

Now it returns a pointer. You can take the pointer of a variable using & and, should you need the struct value itself, dereference it again with *.

After a line like

x := &PaxosInstance{} 

or

p := PaxosInstance{}
x := &p

the value type of x is *PaxosInstance. And if you ever need to, you can dereference it back into a PaxosInstance struct value with

p = *x

You usually do not want to pass structs around as actual values, because Go is pass-by-value, which means it will copy the whole thing. Using struct values with maps and slices often results in logic errors because a copy is made should you iterate them or otherwise reference them except via index. It depends on your use-case, but your identifier Instance would infer that you would want to avoid duplications and such logic errors.

As for reading the compiler errors, you can see what it was telling you. The type PaxosInstance and type *PaxosInstance are not the same.

Tags:

Go