dsvq5069 2017-06-20 07:20
浏览 93
已采纳

如何在Go中为不同类型实现容器? [重复]

This question already has an answer here:

The following code implements a List of ints in Go:

package main

import "fmt"

type List struct {
    Head int
    Tail *List
}

func tail(list List) *List {
    return list.Tail
}

func main() {
    list := List{Head: 1, Tail: 
         &List{Head: 2, Tail:
         &List{Head: 3, Tail:
         nil}}}
    fmt.Println(tail(list).Head)
}

Problem is this only works for int. If I wanted a list of strings, I'd need to re-implement every list method (such as tail) again! That's obviously not practical, so, this can be solved by using an empty interface:

type List struct {
  Head interface{} // Now works for any type!
  Tail *List
}

Problem is, 1. this seems to be much slower because of type casts, 2. it throws aways type safety, allowing one to type-check anything:

// This type-checks!
func main() {
    list := List{Head: 123456789 , Tail:
         &List{Head: "covfefe" , Tail:
         &List{Head: nil       , Tail:
         &List{Head: []int{1,2}, Tail:
         nil}}}}
    fmt.Println(tail(list).Head)

Obviously that program should not type-check in a statically typed language.

How can I implement a List type which doesn't require me to re-implement all List methods for each contained type, but which keeps the expected type safety and performance?

</div>
  • 写回答

3条回答 默认 最新

  • douzhuanfen5923 2017-06-20 07:32
    关注

    Go doesn't have generic types, so you're stuck with the options you listed. Sorry.

    Meanwhile, Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly.

    If you know more about the elements you want to store in the container, you may use a more specialized interface type (instead of the empty interface interface{}), which

    • could help you avoid using type assertions (keep good performance)
    • and still keep type safety
    • and it can be used for all types that (implicitly) implement your interface (code "re-usability", no need to duplicate for multiple types).

    But that's about it. See an example of this here: Why are interfaces needed in Golang?

    Also just in case you missed it, the standard library already has a doubly linked list implementation in the container/list package (which also uses interface{} type for the values).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch