【问题标题】:Initializing a slice by using the var keyword使用 var 关键字初始化切片
【发布时间】:2017-10-29 16:12:59
【问题描述】:

现在我正在学习 Golang,但不了解 Golang 的行为方式。

这里是一个切片的简写声明和初始化:

ilist := []int{1, 2, 3}  //it works

另一方面,如果我尝试使用 var 关键字声明和初始化它,则会出现错误:

var ilist [] int = {1, 2, 3, 4, 5}  //error

如果我只初始化一个变量(而不是切片),它可以正常工作:

var i int = 5 // works fine

为什么Golang会这样,有什么具体原因吗?

【问题讨论】:

  • 我对 Go 没有经验,但我快速浏览了语言规范。你试过var ilist []int = []int{1, 2, 3}吗?与诸如数字或字符串之类的基本文字相比,像切片这样的复合文字需要类型。您也可以省略 var 名称后的类型:var ilist = []int{1, 2, 3}
  • 是的,你说得对,但仍然很奇怪,因为我提供了所有信息以在声明的左侧创建复合文字 (var ilist [] int )。

标签: go initialization slice literals


【解决方案1】:

我提供所有信息来创建复合文字

事情就是这样:您没有提供创建复合文字所需的所有信息。查看Spec: Composite literals 部分以了解需要什么。

这个字面量:

{1, 2, 3, 4, 5}

这个字面量缺少 type 信息。它可以是[]int{} 文字的一部分,也可以是[]float32{} 文字的一部分,甚至可以是结构文字的一部分,其中结构类型具有int 字段(例如type Ints struct{a,b,c,d,e int}) .

是的,在这个变量声明中

var ilist [] int = {1, 2, 3, 4, 5}  //error

只有 []int{} 字面意思是有意义的,但这不是 Go 的工作方式。仅仅因为只有一种类型可以使该行有效,并不意味着您可以省略它。

请注意,如果可以从初始化表达式中推断出类型,则可以从声明中省略类型,因此这两种形式都是有效的:

var ilist1 []int = []int{1, 2, 3, 4, 5}

var ilist2 = []int{1, 2, 3, 4, 5}

但是{1, 2, 3, 4, 5} 的类型会模棱两可(如果它有效的话)。

还请注意,如果您为 [][]int 之类的类型指定复合文字,您可以省略元素的(子)文字中的类型,因为它是从复合文字的类型,所以这也是有效的:

var iilist = [][]int{
    {1, 2, 3},
    {4, 5, 6},
}

地图文字也是如此,这是有效的(在Go 1.5中添加):

var imap = map[int][]int{
    1: {1, 2, 3},
    2: {4, 5, 6},
}

Go Playground 上试试这些。

【讨论】:

    【解决方案2】:

    继续,different names mean different types。所以当你定义一个变量时,你必须指定它的类型。这意味着,您需要确保您的分配是具体类型。 “{}”可以是多个类型,所以编译器找不到ilist类型。顺便说一句,有朋友讨论Proposal: Alias declarations for Go

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 1970-01-01
      • 2020-11-10
      • 1970-01-01
      • 1970-01-01
      • 2017-01-22
      • 1970-01-01
      • 2017-05-26
      • 2013-04-04
      相关资源
      最近更新 更多