登录
首页 >  Golang >  Go问答

类型参数引起的函数调用焦虑

来源:stackoverflow

时间:2024-03-23 11:00:32 349浏览 收藏

在 Go 中,使用类型参数自定义结构体字段相等性时,可能会遇到函数调用恐慌。这是因为接口转换错误,导致无法将类型参数化的接口类型转换为具体类型。

问题内容

我在 go 中有一个结构体,它代表一个状态。我现在希望能够比较两种状态(当前状态和期望状态), 将每个字段与其他字段进行比较。如果所有字段都“相等”,我将两个状态定义为“相等”。 然而,在某些情况下,字段相等性相当松散,我希望自定义定义。

假设“restartedafter”中的状态字段之一。如果当前状态 restartedafter 大于所需状态 restartedafter,那么我认为两者“相等”。

在示例中,我仅使用单个字段,但由于我想迭代结构的所有字段(在下一步中), 我考虑过使用类型参数来定义一个 assertequal() 接口,其中状态结构中的所有字段 应该实施。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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:接口转换:main.statefield[go.shape.int_0] 是 main.restartedafter,而不是 main.restartedafter(来自不同范围的类型)

有什么问题的想法吗?


正确答案


我相信这是此处描述的错误: https://github.com/golang/go/issues/53376

要修复当前版本,您可以重新分配变量:

1
2
3
4
5
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

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《类型参数引起的函数调用焦虑》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>