我正在玩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伙计们!
答案 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)