【发布时间】:2017-07-18 15:48:43
【问题描述】:
也许我并不完全了解泛型的强大功能,但是空接口interface{} 与泛型有何不同,尤其是在我们能够使用反射或类型开关的情况下?人们总是提到 Go 没有泛型,但 interface{} 似乎完成的工作与 Java 中的 <T> 类似。
【问题讨论】:
也许我并不完全了解泛型的强大功能,但是空接口interface{} 与泛型有何不同,尤其是在我们能够使用反射或类型开关的情况下?人们总是提到 Go 没有泛型,但 interface{} 似乎完成的工作与 Java 中的 <T> 类似。
【问题讨论】:
如果您来自 Java,空接口 (interface{}) 实际上更接近于在 Java 中使用 Object 变量而不是泛型。
您可以将任何内容分配给 interface{}(就像您可以在 Java 中使用 Object 变量一样)。
但是,如果您想使用存储在其中的实际类型,则应该“强制转换”或“类型断言”(与 Java 中的 Object 变量相同)。
Java 中的泛型完全不同,因为它们允许您在编译时进行类型检查。不同之处在于,如果您使用泛型,则无需使用反射或类型开关。
您可以在此处阅读有关 Java 泛型的更多信息:
https://docs.oracle.com/javase/tutorial/java/generics/
然后按照此处以及 Go 导览的接下来的 2 或 3 个步骤操作,了解有关空界面如何工作的更多信息:
【讨论】:
考虑到泛型的要点是在提供编写与类型无关的函数/方法的工具时维护静态类型语言的编译时类型安全检查,具有运行时类型断言/开关的空接口与泛型完全不同,我'会说它在编程范式方面几乎与泛型完全相反。
我想说过去十年中超过一半的编程语言改进都是为了避免运行时错误,我想这就是为什么 Go 有一些“内置泛型”比如 slice 和 map 而不是像旧的 JavaScript 的东西在运行时仅对其元素进行类型检查的数组内容。所以 Go 中带有类型断言/开关的空接口绝对不能替代泛型,我个人会尽量避免使用空接口。
【讨论】: