英文:
Type Parameter Panicking in Function Call
问题
我在Go语言中有一个表示状态的结构体,现在我想要能够比较两个状态(当前状态和期望状态),其中每个字段都与另一个字段进行比较。如果所有字段都相等,我将定义两个状态为"相等"。然而,在某些情况下,字段的相等性比较宽松,我希望能够自定义定义。
假设状态字段之一是"RestartedAfter"。如果当前状态的"RestartedAfter"大于期望状态的"RestartedAfter",那么我认为这两个状态是"相等"的。
在这个示例中,我只使用了一个字段,但是由于我想要迭代结构体的所有字段(在下一步中),我考虑使用类型参数来定义一个AssertEqual()
接口,所有状态结构体中的字段都应该实现。
type StateField[T any] interface {
AssertEqual(T) error
}
type RestartedAfter int
func (current RestartedAfter) AssertEqual(desired RestartedAfter) error {
if current >= desired {
return nil
}
return errors.New("current RestartedAfter happened before desired RestartedAfter")
}
func compareTwo[T any](x StateField[T], y T) error {
return x.AssertEqual(y) // panics
}
func main() {
r1 := RestartedAfter(1)
r2 := RestartedAfter(2)
err := compareTwo[RestartedAfter](r1, r2)
if err != nil {
os.Exit(1)
}
}
然而,这个示例会导致程序崩溃。我得到以下错误信息:"panic: interface conversion: main.StateField[go.shape.int_0] is main.RestartedAfter, not main.RestartedAfter (types from different scopes)"。
有什么想法是出了什么问题吗?
英文:
I have a struct in Go, which represents a state. I now want to be able to compare two states (current & desired),
whereby each field is compared with the other. I define two states as "equal" if all fields are "equal".
However, in some cases, field equality is rather loose, which I want to be customely define.
Let's say one of the state fields in "RestartedAfter". If current-state RestartedAfter is greater than desired-state
RestartedAfter, then I consider the two "equal".
In the example I only use a single field, but since I want to iterate over all fields of the struct (in the next step),
I thought about using type parameters to define an AssertEqual()
interface, which all fields in the state-struct
should implement.
type StateField[T any] interface {
AssertEqual(T) error
}
type RestartedAfter int
func (current RestartedAfter) AssertEqual(desired RestartedAfter) error {
if current >= desired {
return nil
}
return errors.New("current RestartedAfter happened before desired RestartedAfter")
}
func compareTwo[T any](x StateField[T], y T) error {
return x.AssertEqual(y) // panics
}
func main() {
r1 := RestartedAfter(1)
r2 := RestartedAfter(2)
err := compareTwo[RestartedAfter](r1, r2)
if err != nil {
os.Exit(1)
}
}
This example however panics. I get the following message: panic: interface conversion: main.StateField[go.shape.int_0] is main.RestartedAfter, not main.RestartedAfter (types from different scopes)
.
Any ideas of what's wrong?
答案1
得分: 4
我相信这是一个在这里描述的错误:
https://github.com/golang/go/issues/53376
要在当前版本中修复,你可以重新分配变量:
func compareTwo[T any](x StateField[T], y T) error {
a := x
b := y
return a.AssertEqual(b)
}
在最新的开发分支中,不需要修复就可以正常工作:
https://go.dev/play/p/KAPDHQW8RWH?v=gotip
英文:
I believe this is a bug described here:
https://github.com/golang/go/issues/53376
To fix in current version you can reassign the variables:
func compareTwo[T any](x StateField[T], y T) error {
a := x
b := y
return a.AssertEqual(b)
}
It works without the fix in latest dev branch:
https://go.dev/play/p/KAPDHQW8RWH?v=gotip
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论