go - 函数调用中的类型参数 panic

标签 go generics type-parameter

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

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

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

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 。我收到以下消息: panic :接口(interface)转换:main.StateField[go.shape.int_0] 是 main.RestartedAfter,而不是 main.RestartedAfter(来自不同范围的类型)

有什么问题的想法吗?

最佳答案

我相信这是此处描述的错误: 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

关于go - 函数调用中的类型参数 panic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72950258/

相关文章:

go - 为什么Go中的位运算符比除法和模运算慢?

performance - 写入操作成本

java - 类型推断的陌生性

c# - 何时指定约束 `T : IEquatable<T>`,即使它不是严格要求的?

go - 进程中断: signal: killed

parsing - Golang ParseFloat 在示例中不准确

c# - 带有开放泛型的工厂模式

java - 无法从 T 转换为整数

Scala:类型参数中的问号

haskell - 如何在幻像类型的模式匹配中指定类型参数