版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/recall_yesterday/article/details/79100871
golang中有一个比较重要的数据类型,是slice-切片。这个和Python的切片用法大致是一样的。
谈到slice时先要说一下数组。
在C++、C中,数组是固定大小,固定类型的一段连续的内存的数据结构。就像我们写作文的方格纸,格子是固定的。这也就带来了一个问题。我并不知道我要存多少个元素到数组里面怎么办?要是有一种能够让我不必操心大小的结构就好了,于是c++中有了vector。与之对应的go中是slice。
那么该说一下slice是如何使用的了。
go中使用make来创建一个切片。
语法:
stringSlice := make([]string,10,12)
//10,是元素的个数,12是这个切片的容量。容量可以省略,不用显示指定。上面的语句就是创建了一个有10个元素的切片,只是每个元素的值都是默认为空。
stringSlice := make([]string,0)
这是创建了一个空的slice。可以通过append添加元素
那么切片如何初始化呢?
stringSlice := []string{"hello","nihao","hi"}
或者使用一个数组对它初始化,
stringSlice := arr[start:end]
那么与其关联紧密的函数有:append,len,cap,copy见名知意,不再赘述。
如果只是声明一个切片但是没有进行初始化,那么这个切片是空值nil。
那么使用方法说完了,该简单说下原理了。c++出身,就拿自己的经验说下吧。
上学的时候,会自己实现一个c++的vector。其实很简单就可以实现一个动态的数组。
template<typename T>
class Vector{
public:
unsigned int len(){return len;}
unsigned int cap(){return cap;}
void push_back(const T &elem){
if(len >= cap){ ..... }//new 一个新的内存,然后将旧内存的内容拷贝到新的中,然后将新元素放到后面。修改长度,和cap
}
private :
T *dataptr;
unsigned int len;
unsigned int cap;
};
那么go的切片实现,就是和上面的大致一样,一个指针,一个长度,一个容量,指针指向第一个元素。
go中的slice就简单写这里吧。
下面是我遇到一个坑,
slic := make([]int,0,10)
add(slic)
func add(sli []int){
sli = append(sli,1)
}
本以为按照上面的写法,当调用玩add函数后,slic会有数据。但是却是没有的,按照我的理解,传进去的sli是一个引用,所以能够把值带回去。学习的不够深入吧,其实上面的原理就是c中的值传递,add函数中的参数,sli是一个副本而已。改变他没有任何作用
那么如何带回来呢?
func add(sli *[]int){
....
}
或者
func add(sli []int)[]int{
}