Go 编程语言中的任何类型和实现通用列表
Posted
技术标签:
【中文标题】Go 编程语言中的任何类型和实现通用列表【英文标题】:Any type and implementing generic list in go programming language 【发布时间】:2011-10-12 15:34:50 【问题描述】:我正在尝试go programming language。
我对 Go 的简单性感到兴奋,但在玩过它之后我遇到了一些麻烦。
1 .我知道 Go 不支持泛型和继承。 有没有办法实现泛型列表?
我正在考虑使用:
type Any interface
但是如何检查该值是否为 NULL。 我正在寻找与 C 等效的实现
struct List
List* tail;
void* head;
或者使用代数数据类型:
data List a = Nil | Cons a (List a)
2.更高级的要求是为具有特定类型字段的对象制作一些容器? 例如,在 Scala 编程语言中,我可以输入:
val List[Animal type SuitableFood = Grass ]
获取Animals
中的List
,其成员类型为SuitableFood
,即Grass
【问题讨论】:
【参考方案1】:您可以拥有interface
类型的元素列表。你可以放入任何元素,当你取出它时,你必须转换回你想要的类型。这就像您在 C 示例中所做的 void *
一样;并且还喜欢泛型之前的 Java 中的列表,以及没有泛型的 Objective-C 中的列表。 Go 库中的所有容器都执行此操作。
没有泛型,就没有元素类型的编译时检查。
如果你真的想要,你可以实现元素类型的运行时检查,通过使用反射来获取元素类型并根据预期类型检查它们。但是,这可能是矫枉过正。
【讨论】:
【参考方案2】:我知道 Go 不支持泛型 [...]
从 Go 1.18 开始。我希望标准库最终会在当前的 container/list
包中添加通用容器,这样您就不必重新发明***了。
无论如何,作为一个思考练习,您可以复制标准 list.List
并自己添加类型参数:
type Element[T any] struct
next, prev *Element[T]
list *List[T]
Value T
type List[T any] struct
root Element[T]
len int
// simplified constructor
func New[T any]() *List[T]
l := new(List[T])
l.root.next = &l.root
l.root.prev = &l.root
l.len = 0
return l
如您所见,Element
struct 可以有一个 Element
类型的字段,但类型参数必须相同且顺序相同 (source)。
为具有特定类型字段的对象制作一些容器?
您可以通过将约束any
替换为指定所需方法的接口约束来做到这一点,例如:
type Animal interface
SuitableFood() string
type Element[T Animal] struct
// ...
这将类型参数限制为那些实现Animal
接口的参数。
您可以不做的是将类型参数限制为具有特定的字段1。如果您必须强制 T
具有特定值,则可以改为向接口约束添加更具体的方法,例如SuitableFoodGrass()
但这是一个泄漏抽象。接口模型行为,你应该坚持这个原则。
1:从技术上讲,您可以使用带有结构的类型约束,但它不是很有用。
【讨论】:
以上是关于Go 编程语言中的任何类型和实现通用列表的主要内容,如果未能解决你的问题,请参考以下文章