首选声明/初始化方法

时间:2010-10-18 15:29:30

标签: syntax go

我正在玩Google Go 有很多方法可以声明和/或初始化变量 有人可以解释每种方式的优点/缺点(样本,据我所知,下文):

    var strArr0 *[10]string = new([10]string)

    var strArr1 = new([10]string)

    var strArr2 = make([]string,10)

    var strArr3 [10]string

    strArr4 := make([]string,10)

您首选的语法是什么?为什么? 谢谢,SO伙计们!

2 个答案:

答案 0 :(得分:7)

我已经将你的例子编号为1-5,我将在这里介绍它们。希望这有帮助!

var strArr0 *[10]string = new([10]string)  // (1)

这将分配一个长度为10的新字符串数组,并返回指向该数组的指针。

var strArr1 = new([10]string)  // (2)

这与1完全相同。这只是简写,由于Go的类型推断而起作用。它可以进一步缩短为:

strArr1 := new([10]string)  // (2a)

其中1,2,2a都产生完全相同的结果。

var strArr2 = make([]string,10)  // (3)

这会产生一个长度为10的字符串。一个切片指的是底层数组的某个子集。来自the golang spec

  

make()调用分配一个新的,   隐藏的数组返回   切片值是指。

     
make([]T, length, capacity)
  
     

生成与分配数组并对其进行切片相同的切片,    所以这两个例子产生了相同的切片:

     
make([]int, 50, 100)
new([100]int)[0:50]
  

所以3等同于以下任何一个:

var strArr2 = new([10]string)[0:10]  // Slicing an explicitly created array
var strArr2 []string = new([10]string)[0:10]  // Explicitly declaring the type of strArr2, rather than inferring
strArr2 := new([10]string)[0:10]  // Using the := shorthand instead of var
根据您正在创建的类型,使用

new或make。 make仅用于切片,地图和通道。他们使用了一个不同的关键字来传达这样的想法:make正在初始化一些数据结构,而不仅仅是将内存归零。

下一个回到数组而不是切片:

var strArr3 [10]string  // (4)

这与1,2和2a相同。

strArr4 := make([]string,10)  // (5)

与3.:=相同,只是初始化变量时的简写,可以推断出类型。


那么选择哪个?这取决于您的个人风格,但一般来说,一个选择显然是最大限度地提高代码的清晰度,例如:当类型明显时使用类型推断:

foo := bar.ToStringArray()

或在不太常见的情况下声明类型,类型将有助于查看:

var foo []string = bar.DoSomethingOpaque()

在切片与数组之间,您通常会为您正在调用的某个函数创建所需的任何类型。

答案 1 :(得分:2)

首先,您应该了解数组和切片之间的区别。数组被视为值,因此如果将它们传递给函数,它们将被复制。另一方面,切片是对底层数组的引用,因此如果将切片传递给函数,函数变量仍将引用相同的底层数组。

在您的示例中,前两个是相同的,它只是第一个指定变量声明中的类型。让你这样做,在某些情况下它可能有所帮助 - 比如当你试图将一个变量声明为一个接口而不是一个值时(即var i io.Reader = os.Open(...))

第三个和第五个(var strArr2 = make([]string,10)strArr4 := make([]string,10)是等价的,但后者使用变量声明的简写形式,这通常可以节省大量的输入。

第四个只声明一个数组值。

除非我正在处理网络数据,否则我很少在代码中处理数组。所以我的首选语法是:

s := make([]string, 10)