也许我并不完全精通泛型的力量,但是空接口interface{}与泛型有什么不同,特别是如果我们能够使用反射或类型开关的话?人们总是提到Go没有泛型,但interface{}似乎可以与Java中的<T>相媲美。
interface{}
<T>
sauutmhj1#
如果你来自Java,空接口(interface{})实际上更接近于使用Java中的Object变量,而不是泛型。您可以将任何内容分配给interface{}(就像在Java中对Object变量所做的那样)。但是如果你想使用你存储在那里的实际类型,你应该“强制转换”或“类型Assert”(和Java中的Object变量一样)。Java中的泛型非常不同,因为它们允许您在编译时进行类型检查。不同之处恰恰在于,如果使用泛型,则不需要求助于反射或类型开关。你可以在这里阅读更多关于Java泛型的内容:https://docs.oracle.com/javase/tutorial/java/generics/然后按照Go教程的下面2或3个步骤来了解空接口的工作原理:https://tour.golang.org/methods/14
Object
67up9zun2#
考虑到泛型的主要观点是在提供编写类型不可知函数/方法的工具时维护静态类型语言的编译时类型安全检查,带有运行时类型Assert/开关的空接口与泛型完全不同,我想说它在编程范式方面几乎与泛型完全相反。我想说,在过去十年中,超过一半的编程语言改进都是关于避免运行时错误的,我想这就是为什么Go有一些“内置泛型”,比如切片和Map,而不是像旧的JavaScript的数组那样,在运行时只对元素进行类型检查。因此,Go语言中带有类型Assert/开关的空接口绝对不能替代泛型,就我个人而言,我会尽可能避免使用空接口。
2条答案
按热度按时间sauutmhj1#
如果你来自Java,空接口(
interface{}
)实际上更接近于使用Java中的Object
变量,而不是泛型。您可以将任何内容分配给
interface{}
(就像在Java中对Object
变量所做的那样)。但是如果你想使用你存储在那里的实际类型,你应该“强制转换”或“类型Assert”(和Java中的
Object
变量一样)。Java中的泛型非常不同,因为它们允许您在编译时进行类型检查。不同之处恰恰在于,如果使用泛型,则不需要求助于反射或类型开关。
你可以在这里阅读更多关于Java泛型的内容:
https://docs.oracle.com/javase/tutorial/java/generics/
然后按照Go教程的下面2或3个步骤来了解空接口的工作原理:
https://tour.golang.org/methods/14
67up9zun2#
考虑到泛型的主要观点是在提供编写类型不可知函数/方法的工具时维护静态类型语言的编译时类型安全检查,带有运行时类型Assert/开关的空接口与泛型完全不同,我想说它在编程范式方面几乎与泛型完全相反。
我想说,在过去十年中,超过一半的编程语言改进都是关于避免运行时错误的,我想这就是为什么Go有一些“内置泛型”,比如切片和Map,而不是像旧的JavaScript的数组那样,在运行时只对元素进行类型检查。因此,Go语言中带有类型Assert/开关的空接口绝对不能替代泛型,就我个人而言,我会尽可能避免使用空接口。