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

时间:2015-10-13 20:21:44

标签: go interface

我正在编写一些数据结构,以便让我的脚湿透,并了解Go语言,并且正在努力解决Go缺乏的泛型问题。

在我的实现中,我选择强制每个用户实现一个接口,所以我的结构可以抽象地引用这些对象,但我不喜欢我的解决方案,因为这不会在编译时验证,如你所见。

Comparer Interface

容器中保存的每个对象都必须实现以下签​​名的Compare函数(如果你想要保留的只是原始类型,那就很麻烦)

type Comparer interface {
    Compare(Comparer) int
}

然后,您可以拥有实现接口的各种元素,如float64或自定义结构:

float64

type number float64

func (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
}

这里的问题是我无法比较Personnumber。我意识到我可以在运行时检查类型,但我想找到a)编译时验证类型的方法或b)一般实现数据结构的不同方法。

问题

  1. 我知道人们几乎可以使用内置数据结构完成所需的一切...... 但是如果没有泛型或运行时类型检查,有人会如何创建自己的数据结构?
  2. 由于Go中的接口实现似乎使用duck typing,Go如何在编译时强制执行类型?

1 个答案:

答案 0 :(得分:2)

我的意思是代码没有什么不安全的......没有编译时安全性。例如,在下面的方法中,第一行在comparer上执行类型断言,如果它不是数字而你没有_用于LHS上的第二项,那么它将返回错误,你可以采取相应的行动。或者你可以在没有它的情况下调用它,并且会发生panic将它留给调用者来处理它(因为他们是用错误的参数调用方法的人,就像得到一个{在C#中{1}}。

InvalidOperationException

这与C#之类的语言之间的区别仅仅在于泛型,它允许您以更快的编译时间来执行这些类型的事情(因为您无法正确调用该方法)。话虽这么说,有一段时间C#之前有泛型和许多语言,但根本没有它们。这些操作并不比你常规执行的强制转换更不安全,即使在 具有泛型的语言中也是如此。