从c到golang(2.struct slice和映射)
struct slice和映射
结构体struct 是一组字段 field,使用.访问
type Vertex struct {
X int
Y int
}
花括号的使用原来落在了这里
v :=Vertex{1, 2}
v.x = 5
fmt.Println(v.x)
结构体的指针可以当作结构体变量使用(语法糖)
v :=Vertex{1, 2}
p = &v
p.X 等价于 (*p).X 等价于 v.X 等价于1
结构体可以单独给某个字段赋值,其余会隐式赋值默认值
v2 = Vertex{X: 1} // Y:0 被隐式地赋予
v2内容为{1,0}
数组
声明
var a [10]int
可以基于数组,创建一个切片,动态扩展,但又不同于oc中的mutableArray,切片更像是数组的引用,对切片的修改会影响到数组和基于该数组的其他切片.或者说不是mutableCopy性质的.
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4]
fmt.Println(s)
输出为2,3,4
包含冒号前,不包括冒号后的..
因为上面切片的特性,所以常见直接初始化切片,并直接操作切片,虽然其背后是有一个匿名数组存在
q := []int{2, 3, 5, 7, 11, 13}
创建一个匿名数组,然后构建一个引用了它的切片,保存为q
切片使用冒号切片,可以不填来默认上下界
var a [10]int
以下切片等价
a[0:10]
a[:10]
a[0:]
a[:]
切片的容量是从自己第一个开始,到其依赖的底层数组最后一个(最多就到这里了),切片的长度是自己第一个到自己最后一个的元素数.所以容量>=长度
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
printSlice(s)
// 截取切片使其长度为 0
s = s[:0]
printSlice(s)
// 拓展其长度
s = s[:4]
printSlice(s)
// 舍弃前两个值
s = s[2:]
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
输出
len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=4 cap=6 [2 3 5 7]
len=2 cap=4 [5 7]
使用make来创建切片,这里很关键,实践中很多这种用法
a := make([]int, 5) // len(a)=5
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
再切两次
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
内建函数append向切片中添加元素,可无限添加,切片的底层数组会动态调整
package main
import "fmt"
func main() {
var s []int
printSlice(s)
// 添加一个空切片
s = append(s, 0)
printSlice(s)
// 这个切片会按需增长
s = append(s, 1)
printSlice(s)
// 可以一次性添加多个元素
s = append(s, 2, 3, 4)
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
输出
len=0 cap=0 []
len=1 cap=2 [0]
len=2 cap=2 [0 1]
len=5 cap=8 [0 1 2 3 4]
使用for range来遍历切片,返回值为索引和值拷贝,可以使用_来忽略
package main
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
for i,_ := range pow{
//do something with index i
}
}
输出
2**0 = 1
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128
go中的字典map称为映射,可以使用make声明,再设置值(alloc即视感)
注意映射最后的一个,不能省略
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
fmt.Println(m["Bell Labs"])
//或者可以这样
m["Bell Labs"] = {40.68433, -74.39967,}
}
输出
{40.68433 -74.39967}
也可以在初始化时候直接赋值,此时不用make
var m = map[string]string{
"Bell Labs": "贝尔实验室",
"Google":"谷歌",
}
//增,改
m["Google"] = "跟中国有不解之缘"
//删
delete(m,"Google")
//get
s = m["Google"]
//get同时判断是否存在该key
value,hasKey := m["Google"]
value 为 "跟中国有不解之缘"
hasKey 为 true
使用函数做参数
package main
import (
"fmt"
"math"
)
func compute(fn func(float64, float64) float64) float64 {
return fn(3, 4)
}
func main() {
hypot := func(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(5, 12))
fmt.Println(compute(hypot))
fmt.Println(compute(math.Pow))
}
输出
13
5
81
版权属于:邢迪的平行时空
本文链接:https://xingdi.me/archives/38.html
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可