Cannot use as type in assignment in go

huangapple go评论88阅读模式
英文:

Cannot use as type in assignment in go

问题

当我编译我的代码时,我得到了以下错误消息,不确定为什么会发生这种情况。有人可以帮我指出原因吗?提前谢谢。

无法将px.InitializePaxosInstance(val)(类型为PaxosInstance)作为类型*PaxosInstance分配

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 
}
英文:

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 
}

答案1

得分: 27

你的地图期望接收一个指向PaxosInstance的指针(*PaxosInstance),但你却传递了一个结构体值。将你的Initialize函数修改为返回一个指针。

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

现在它返回一个指针。你可以使用&来获取一个变量的指针,并且如果你需要结构体值本身,可以再次使用*进行解引用。

在类似以下的代码行之后:

x := &PaxosInstance{}

或者

p := PaxosInstance{}
x := &p

x的值类型是*PaxosInstance。如果需要的话,你可以通过以下方式将其再次解引用为PaxosInstance结构体值:

p = *x

通常情况下,你不希望将结构体作为实际值传递,因为Go是按值传递的,这意味着它会复制整个结构体。在使用结构体值与映射和切片时,经常会导致逻辑错误,因为在迭代或通过索引以外的方式引用它们时会进行复制。这取决于你的用例,但是你的标识符Instance表明你希望避免重复和此类逻辑错误。

至于如何阅读编译器错误,你可以看到它告诉你什么。类型PaxosInstance和类型*PaxosInstance是不同的。

英文:

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.

答案2

得分: 6

Paxos 结构体中的 instance 字段是一个从整数键到 PaxosInstance 结构体指针的映射。

当你调用:

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

你试图将一个具体的(非指针)PaxosInstance 结构体赋值给 px.instance 的一个元素,而这些元素是指针。

你可以通过在 InitializePaxosInstance 中返回一个 PaxosInstance 的指针来解决这个问题,像这样:

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

或者你可以修改 Paxos 结构体中的 instance 字段,使其不再是指针的映射:

type Paxos struct {
    instance   map[int]PaxosInstance
}

选择哪个选项取决于你的使用情况。

英文:

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.

答案3

得分: 3

对于其他人来说,如果你正在为此问题苦恼,请检查你的导入语句。

我不确定这个问题是什么时候开始出现的,但是我的 Visual Studio Code + gopls 设置有时会插入一个导入语句,引用的是我的依赖库的路径,而不是原始的导入路径。通常我直到开始准备发布代码或者出现类似这样的错误时才会注意到这个问题。

在我的情况下,这导致两个本来相同的类型无法相等比较。一旦我修复了我的导入语句,这个错误就解决了。

英文:

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.

huangapple
  • 本文由 发表于 2017年5月11日 03:04:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/43900806.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定