为了账号安全,请及时绑定邮箱和手机立即绑定

如何确保自定义数据结构中的编译时安全

如何确保自定义数据结构中的编译时安全

Go
catspeake 2021-11-15 16:11:51
我正在编写一些数据结构来让我的脚弄湿并学习 Go 语言,并且正在为 Go 缺乏泛型而苦苦挣扎。在我的实现中,我选择强制每个用户实现一个接口,以便我的结构可以抽象地引用这些对象,但我不喜欢我的解决方案,因为正如您将看到的那样,这在编译时没有得到验证。比较器接口保存在容器中的每个对象都必须实现Compare以下签名的函数(如果您只想保存原始类型,则很麻烦)type Comparer interface {    Compare(Comparer) int}然后,您可以拥有实现接口的各种元素,例如float64或自定义结构:浮动64type number float64func (n1 number) Compare(comparer Comparer) int {    n2, _ := comparer.(number)    if n1 > n2 {        return 1    } else if n1 < n2 {        return -1    } else {        return 0    }}人type Person struct {    Age int}func (p1 Person) Compare(comparer Comparer) int {    p2, _ := comparer.(Person)    if p1.Age > p2.Age {        return 1    } else if p1.Age < p2.Age {        return -1    } else {        return 0    }}现在我可以比较其中的一些东西:func main() {    fmt.Println(number(2).Compare(number(4)))    // -1    fmt.Println(Person{26}.Compare(Person{28}))  // -1    fmt.Println(Person{26}.Compare(number(28)))  //  1}这里的问题是我不应该比较 aPerson和 a number。我意识到我可以在运行时检查类型,但我想找到 a) 一种验证类型的编译时方法或 b) 一种不同的方法来通用地实现数据结构。问题我知道使用内置数据结构几乎可以做任何可能需要的事情……但是如果没有泛型或运行时类型检查,人们如何制作自己的数据结构呢?由于 Go 中的接口实现似乎使用了鸭子类型,那么 Go 在编译时如何强制类型?
查看完整描述

1 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

我的意思是该代码没有任何不安全的地方......只是没有编译时安全。例如,在您下面的方法中,第一行对 进行类型断言comparer,如果它不是数字并且您没有_LHS 上的第二项,那么它将返回一个错误,您可以采取相应的行动。或者你可以在没有它的情况下调用它,并且panic会发生将它留给调用者来处理它(这很合适,因为他们是用错误的参数调用方法的人,就像InvalidOperationException在 C# 中得到一个一样)。


func (n1 number) Compare(comparer Comparer) int {

    n2, _ := comparer.(number)

    if n1 > n2 {

        return 1

    } else if n1 < n2 {

        return -1

    } else {

        return 0

    }

}

这与像 C# 这样的语言之间的区别纯粹在于泛型,它允许您以更高的编译时安全性来执行这些类型的事情(因为您不能错误地调用该方法)。话虽如此,在 C# 有泛型之前有一段时间,而在此之前的许多语言根本没有它们。即使在具有泛型的语言中,这些操作也不会比您经常进行的转换更不安全。


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 168 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信