【问题标题】:How is the empty interface different than a generic?空接口与泛型接口有何不同?
【发布时间】:2017-07-18 15:48:43
【问题描述】:

也许我并不完全了解泛型的强大功能,但是空接口interface{} 与泛型有何不同,尤其是在我们能够使用反射或类型开关的情况下?人们总是提到 Go 没有泛型,但 interface{} 似乎完成的工作与 Java 中的 <T> 类似。

【问题讨论】:

    标签: generics go


    【解决方案1】:

    如果您来自 Java,空接口 (interface{}) 实际上更接近于在 Java 中使用 Object 变量而不是泛型。

    您可以将任何内容分配给 interface{}(就像您可以在 Java 中使用 Object 变量一样)。

    但是,如果您想使用存储在其中的实际类型,则应该“强制转换”或“类型断言”(与 Java 中的 Object 变量相同)。

    Java 中的泛型完全不同,因为它们允许您在编译时进行类型检查。不同之处在于,如果您使用泛型,则无需使用反射或类型开关。

    您可以在此处阅读有关 Java 泛型的更多信息:

    https://docs.oracle.com/javase/tutorial/java/generics/

    然后按照此处以及 Go 导览的接下来的 2 或 3 个步骤操作,了解有关空界面如何工作的更多信息:

    https://tour.golang.org/methods/14

    【讨论】:

    • Go 的主要区别是在运行时而不是编译时检查?
    • 是的。由于 Go 没有“泛型”功能,您可以使用 interface{} 并进行运行时检查(与 Java 开发人员在泛型进入语言之前所做的相同)。请注意,Go 中的集合(切片、映射)是有类型的,因此对泛型的需求并不那么重要,因为集合是您需要此功能的最突出的地方。
    • 嗯,也可以通过简单地调用函数来检查接口是否在编译时实现 - 见stackoverflow.com/a/44692363/2969090
    • 该示例不适用于 interface{} 变量,而是使用类型变量。您可以在编译时检查类型是否实现了接口,但无法在编译时检查接口{} 是否属于给定类型。
    • 更不用说 Go,类型断言允许你查看和使用底层类型。使用泛型,您实际上是在放弃了解您的类型。
    【解决方案2】:

    考虑到泛型的要点是在提供编写与类型无关的函数/方法的工具时维护静态类型语言的编译时类型安全检查,具有运行时类型断言/开关的空接口与泛型完全不同,我'会说它在编程范式方面几乎与泛型完全相反。

    我想说过去十年中超过一半的编程语言改进都是为了避免运行时错误,我想这就是为什么 Go 有一些“内置泛型”比如 slice 和 map 而不是像旧的 JavaScript 的东西在运行时仅对其元素进行类型检查的数组内容。所以 Go 中带有类型断言/开关的空接口绝对不能替代泛型,我个人会尽量避免使用空接口。

    【讨论】:

    • 添加到您的出色答案中。 Golang 现在为泛型编程的类型参数提供实验性支持。见jetbrains.com/help/go/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多