Go编程语言中的任意类型和实现泛型列表
我正在尝试一些 go 编程语言。
我对 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
I'm trying a little of go programming language.
I'm a excited about the simplicity of the Go, but after playing with it I met some troubles.
1 . I know that Go doesn't support generics and inheritance. Is there any way to implement generic list?
I thinking about using:
type Any interface { }
but how can I check if the value is NULL.
I'm looking for some equivalent implementation to C
struct List {
List* tail;
void* head;
}
Or using algebraic datatype:
data List a = Nil | Cons a (List a)
2 . More advanced requirement would be to make some container for objects with a field of a particular type?
For example in Scala programming language I can type:
val List[Animal { type SuitableFood = Grass} ]
to get a List
of Animals
, which have a member type SuitableFood
which is Grass
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以拥有
interface{}
类型的元素列表。你可以放入任何元素,当你取出它时,你必须转换回你想要的类型。这就像您在 C 示例中所做的void *
;也像 Java 中没有泛型之前的列表,以及 Objective-C 中没有泛型的列表。 Go 库中的所有容器都执行此操作。如果没有泛型,就无法对元素类型进行编译时检查。
如果您确实想要,可以通过使用反射来获取元素类型并根据预期类型检查它们来实现元素类型的运行时检查。然而,这可能有点矫枉过正了。
You can have a list of elements of type
interface{}
. You can put any elements in, and when you get it out, you have to cast back to the type you want. This is like what you're doingvoid *
in your C example; and also like lists in Java before Generics, and in Objective-C, which doesn't have generics. All the containers in the Go library do this.Without generics, there is no compile-time checking of the element types.
If you really wanted, you could implement run-time checks for element type, by using reflection to get the element types and checking them against the expected type. However, this is probably overkill.
从 Go 1.18 开始支持泛型。我希望标准库最终能够沿着当前的
container/list
< 添加通用容器/a> 包,这样你就不必重新发明轮子。无论如何,作为思考练习,您可以复制标准
list.List
并自己添加类型参数:如您所见,
Element
结构可以具有类型为Element< 的字段/code>,但类型参数必须相同且顺序相同(来源) 。
您可以通过将约束
any
替换为指定所需方法的接口约束来实现此目的,例如:这会将类型参数限制为实现
Animal
接口的类型参数。您不能做的就是将类型参数限制为具有特定的字段1。如果您必须强制
T
具有特定值,则可以向接口约束添加更具体的方法,例如SuitableFoodGrass()
但这是一个泄漏抽象 /em>.接口对行为进行建模,您应该遵守该原则。1:从技术上讲,您可以使用结构的类型约束,但它不会很有用。
It does as of Go 1.18. I expect the standard library to eventually add generic containers along the current
container/list
package so you don't have to reinvent the wheel.Anyway as a thought exercise you could copy the standard
list.List
and add type parameters yourself:As you can see
Element
struct can have a field of typeElement
, but the type params must be the same ones and in the same order (source).You can do this by replacing the constraint
any
with an interface constraint that specified the method you want, for example:and this constrains the type parameter to those that implement the
Animal
interface.What you can not do is constrain the type param to have a particular field1. If you must force
T
to have specific values, you could instead add a more specific method to the interface constraint, e.g.SuitableFoodGrass()
but that's a leaky abstraction. Interfaces model behavior, and you should stick to that principle.1: Technically you can, using a type constraint with a struct, but it wouldn't be very useful.