go语言基础[2]-复合数据类型

阿彪_0fc0 · · 644 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

数组

数组一般都是指定长度的某种类型 。由于长度无法变化,其实很少使用到。

var a[3] int
var b [3]int = [3]int{1, 2, 3} // 初始化
c := [...]int{1, 2, 3}//简略方式
r := [...]int {99:-1} // 初始化了100个元素,100号位置写-1,其他全部都写0

数组能直接做==的检测判断。
在调用函数的时候,将会赋值给函数的内部变量,如果参数使用了数组,将会存在内存拷贝。如果传递大的数组,将会有性能消耗。而且在修改数组内容时,也是在复制的数组中修改。如果想减少消耗,并且支持同步修改,还是需要使用数组指针方式来传递。

slice

切片是可变长的数组。每个元素都是相同类型。它包含了指针、长度和容量。指针是指向自己持有的slice的第一个元素,不一定是真实的数组中的第一个。长度,就是当前slice的长度。容积是全部长度。slice可以通过切片方法,分离出子串。其实本质上,他们还是指向同一个数组的。只是由于他们的指针位置不同,而体现出来不一样。
切片的方法 a[n:m]将会取出[n,m)之间的元素出来,产生新的slice。如果n没有填写,默认意思是0,m没有填写,默认就是切片的长度。所以a[:]获取全部内容。
使用make来创建一个slice:
make([]T,len,[cap])
append函数为slice追加内容。如果cap足够,那就直接添加到尾部,否则将重新创数组,将老数组copy进去,将新的内容添加到数组尾部。append都是返回一个新的数组出来,而不会去直接修改老数组。
slice类似这样的数据结构:

type IntSlice struct {
    ptr *int
    len,cap int 
}

在使用slice的时候,需要注意底层存在一个数组。如果能复用,将会大大的提高运行效率。
删除最后一元素
stack = stack[:len(stack)-1]
获取栈顶元素
top := stack[len(stack)-1]
删除其中一个元素

func remove(slice []int, i int) []int {
    copy(slice[i:],slice[i+1:])
    return slice[:len(slice)-1]
}

需要做一次内存拷贝。如果不在乎顺序,可以直接将最后位置的元素,直接赋值掉指定位置的元素,删除slice最后的元素。
在stackoverflow里面的建议是直接使用连接两个拆分的slice,这样反而会比较高效。
原文地址

func remove(slice []int, s int) []int {
    return append(slice[:s], slice[s+1:]...)
}

map

key/value方式无序的集合。golang中的map其实就是哈希表。其中key的类型需要支持==比较运算符。浮点型最好不好当成key。
创建map的方法
ages :=make(map[string]int)
ages := map[string]int {
"alice" : 31,
"Charlie" : 34,
}
map的元素可以通过key下标来访问
ages["alice"]=32
fmt.Println(ages["alice"])
通过delete对map中的元素删除
delete(ages,"alice")
也能直接对不存在的元素直接做操作
ages["bob"] = ages["bob"]+1
系统会自动初始化key为bob的元素并且返回0
map中的元素不是变量,所以无法取得地址。原因也是由于随着元素的删减,可能内存空间有放大,或者缩小。所以取得的内存地址可能失效。
循环方式是
for name,age := range ages {
fmt.Printf("%s\t%d\n",name,age)
}
由于是hash所以遍历的顺序是不固定的。map变量定义出来之后都是nil值。可以通过make语句来创建初始化。
如需要检查一个元素是否有初始化,可以通过
age, ok := ages["bob"]
if !ok {
// 不存在元素。
}
map容器不能直接做比较操作。
go语言没有提供set类型,可以使用map来代替。

结构体

结构体里面可以定义0-n个成员。
type T struct {
a,b int
}
val := &T{a:1,b:2}
如果函数需要修改结构体内容,出于对效率的考虑,一般都是使用结构体的引用作为参数来传递。
结构体的嵌套
type Point struct {
X,Y int
}
type Circle struct {
Center Point
Radius int
}
type Wheel struct {
Circle Circle
Spokes int // 辐条
}
var w Wheel
w.Circle.Center.X = 8
...
go语言中能再struct中定义匿名的成员,这样就直接将其他的struct直接嵌入到了自己的结构体
type Circle struct {
Point
Radius int
}
type Wheel struct {
Circle
Spokes int
}
var w Wheel
w.X = 9
...
struct可以通过
fmt.Printf("%#v\n",w)
输出信息。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:阿彪_0fc0

查看原文:go语言基础[2]-复合数据类型

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

644 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传