【问题标题】:Go: Extending unnamed types such as []stringGo:扩展未命名类型,例如 []string
【发布时间】:2014-12-08 22:23:17
【问题描述】:

我对 Go 中的类型别名有点困惑。

我已经阅读了这个相关的 SO 问题 - Why can I type alias functions and use them without casting?

据我了解,如果底层结构相同,未命名变量和命名变量可以相互分配。

我想弄清楚的是,我可以通过命名来扩展未命名的类型吗?如下所示:

type Stack []string

func (s *Stack) Print() {
    for _, a := range s {
        fmt.Println(a)
    }
}

这给了我错误cannot range over s (type *Stack)
尝试将其投射到 []string,不行。

我知道下面的代码有效 - 我应该这样做吗?如果是这样,我很想知道为什么上述方法不起作用,以及 type Name []string 等声明的用途是什么。

type Stack struct {
    data []string
}

func (s *Stack) Print() {
    for _, a := range s.data {
        fmt.Println(a)
    }
}

【问题讨论】:

  • 你试过for _, a := range *s 吗?
  • s 是一个指向 Stack 的指针,因此是一个指向 []string 的指针,在 Go 中你不能在指针上进行范围。 range *s 可以。这与“命名”或“未命名”类型或别名无关,它只是静态类型的结果,并且您的 s 具有错误的范围类型。
  • 在 Go 中,没有类型别名之类的东西。 type 关键字引入了新的命名类型。它们不是别名。 (与其他各种语言相比,这是 Go 的重要优势之一)

标签: go


【解决方案1】:

你应该取消引用指针 s

type Stack []string

func (s *Stack) Print() {
    for _, a := range *s {
        fmt.Println(a)
    }
}

【讨论】:

  • 太棒了!很简单。出于某种原因,我寻找了复杂的解决方案。我想这是因为 Go 编译器宠坏了我——它通常让我知道 *type 何时用作 type。非常感谢。
  • Francesc Campoy (Google) 有一个很棒的演示文稿,他总结了在哪些情况下可以使用 *T 或 T 以及何时不同。 speakerdeck.com/campoy/things-i-learned-teaching-go 从第 38 页开始。
猜你喜欢
  • 2017-11-24
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多