when I compile my code, I get the following error message, not sure why it happens. Can someone help me point why? Thank you in advance.
cannot use px.InitializePaxosInstance(val) (type PaxosInstance) as type *PaxosInstance in assignment
type Paxos struct {
instance map[int]*PaxosInstance
}
type PaxosInstance struct {
value interface{}
decided bool
}
func (px *Paxos) InitializePaxosInstance(val interface{}) PaxosInstance {
return PaxosInstance {decided:false, value: val}
}
func (px *Paxos) PartAProcess(seq int, val interface{}) error {
px.instance[seq] = px.InitializePaxosInstance(val)
return nil
}
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With