原文链接: Go 语言数组和切片的区别
在 Go 语言中,数组和切片看起来很像,但其实它们又有很多的不同之处,这篇文章就来说说它们到底有哪些不同。
另外,这个问题在面试中也经常会被问到,属于入门级题目,看过文章之后,相信你会有一个很好的答案。
数组是同一种数据类型元素的集合,数组在定义时需要指定长度和元素类型。

例如:[4]int 表示一个包含四个整数的数组,数组的大小是固定的。并且长度是其类型的一部分([4]int 和 [5]int 是不同的、不兼容的类型)。
数组元素可以通过索引来访问,比如表达式 s[n] 表示访问第 n 个元素,索引从零开始。
func main() {
var nums [3]int // 声明并初始化为默认零值
var nums1 = [4]int{1, 2, 3, 4} // 声明同时初始化
var nums2 = [...]int{1, 2, 3, 4, 5} // ...可以表示后面初始化值的长度
fmt.Println(nums) // [0 0 0]
fmt.Println(nums1) // [1 2 3 4]
fmt.Println(nums2) // [1 2 3 4 5]
}
如果数组作为函数的参数,那么实际传递的是一份数组的拷贝,而不是数组的指针。这也就意味着,在函数中修改数组的元素是不会影响到原始数组的。

package main
import (
"fmt"
)
func Add(numbers [5]int) {
for i := 0; i < len(numbers); i++ {
numbers[i] = numbers[i] + 1
}
fmt.Println("numbers in Add:", numbers) // [2 3 4 5 6]
}
func main() {
// declare and initialize the array
var numbers [5]int
for i := 0; i < len(numbers); i++ {
numbers[i] = i + 1
}
Add(numbers)
fmt.Println("numbers in main:", numbers) // [1 2 3 4 5]
}
数组的使用场景相对有限,切片才更加常用。
切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。

切片是一种引用类型,它有三个属性:指针,长度和容量。
底层源码定义如下:
type slice struct {
array unsafe.Pointer
len int
cap int
}
func main() {
var nums []int // 声明切片
fmt.Println(len(nums), cap(nums)) // 0 0
nums = append(nums, 1) // 初始化
fmt.Println(len(nums), cap(nums)) // 1 1
nums1 := []int{1,2,3,4} // 声明并初始化
fmt.Println(len(nums1), cap(nums1)) // 4 4
nums2 := make([]int,3,5) // 使用make()函数构造切片
fmt.Println(len(nums2), cap(nums2)) // 3 5
}
当切片作为函数参数时,和数组是不同的,如果一个函数接受一个切片参数,它对切片元素所做的更改将对调用者可见,类似于将指针传递给了底层数组。
package main
import (
"fmt"
)
func Add(numbers []int) {
for i := 0; i < len(numbers); i++ {
numbers[i] = numbers[i] + 1
}
fmt.Println("numbers in Add:", numbers) // [2 3 4 5 6]
}
func main() {
var numbers []int
for i := 0; i < 5; i++ {
numbers = append(numbers, i+1)
}
Add(numbers)
fmt.Println("numbers in main:", numbers) // [2 3 4 5 6]
}
再看一下上面的例子,把参数由数组变成切片,Add 函数中的修改会影响到 main 函数。
最后来总结一下,面试时也可以这么来回答:
以上就是本文的全部内容,如果觉得还不错的话欢迎点赞,转发和关注,感谢支持。
参考文章:
推荐阅读:
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>