1. 数组与切片
- 定义 ```go var a [3]int //数组 var a []int //切片
b := [3]int{1,2,3} //数组 c := […]int{1,2,3} //数组 b := []int{1,2,3} //切片
数组需要指定长度或用 `...` 表示长度,切片定义不指定长度。
- **遍历**
```go
func TestArrayTravel(t *testing.T) {
arr := [...]int{1, 2, 3, 4, 5}
slice := []int{1, 2, 3, 4, 5}
for i := 0; i < len(arr); i++ {
t.Log(arr[i])
t.Log(slice[i])
}
for idx, e := range arr {
t.Log(idx, e)
}
for idx, e := range arr {
t.Log(idx, e)
}
for idx, e := range slice {
t.Log(idx, e)
}
for _, e := range arr {
t.Log(e)
}
for _, e := range slice {
t.Log(e)
}
}
切片与数组在遍历特征上没有任何差别有三种遍历方式:
for i
使用下表访问for idx,e : range
迭代访问下标和元素for _,e : range
迭代仅访问元素- 截取 ```go func TestArrayCult(t *testing.T) { arr := […]int{1, 2, 3, 4, 5} arr1 := arr[:3] t.Log(arr1) arr1 = arr[1:3] arr1 = append(arr1, 99) t.Log(arr1, arr) arr1 = arr[1:] t.Log(arr1) arr1 = arr[1:len(arr)] t.Log(arr1) arr1[0] = 100 t.Log(arr, arr1) } === RUN TestArrayCult TestArrayCult: array_test.go:47: [1 2 3] TestArrayCult: array_test.go:50: [2 3 99] [1 2 3 99 5] TestArrayCult: array_test.go:52: [2 3 99 5] TestArrayCult: array_test.go:54: [2 3 99 5] TestArrayCult: array_test.go:56: [1 100 3 99 5] [100 3 99 5] —- PASS: TestArrayCult (0.00s) PASS
// slice的内存共享 func TestSliceShareMemory(t *testing.T) { year := []string{“Jab”, “Feb”, “Mar”, “Apr”, “May”, “Jun”, “Jul”, “Aug”, “Sep”, “Oct”, “Nov”, “Dec”} Q2 := year[3:6] t.Log(Q2, len(Q2), cap(Q2))
summer := year[5:8]
t.Log(summer, len(summer), cap(summer), year[8])
summer = append(summer, "what?")
t.Log(summer, len(summer), cap(summer), year[8])
summer[0] = "Unknown"
t.Log(Q2)
t.Log(year)
} === RUN TestSliceShareMemory TestSliceShareMemory: slice_test.go:36: [Apr May Jun] 3 9 TestSliceShareMemory: slice_test.go:38: [Jun Jul Aug] 3 7 Sep TestSliceShareMemory: slice_test.go:40: [Jun Jul Aug what?] 4 7 what? TestSliceShareMemory: slice_test.go:43: [Apr May Unknown] TestSliceShareMemory: slice_test.go:44: [Jab Feb Mar Apr May Unknown Jul Aug what? Oct Nov Dec] —- PASS: TestSliceShareMemory (0.00s) PASS
- 采用 `a[n,m]` 方式截取,n包含,m不包含
- n或m可省略,表示从头开始或者截取到末尾
- 截取后的存储空间是共享的,capacity为截取始点所有原切片的长度
- 修改截取后的数据会影响原数组/切片
- append数组/切片后会覆盖原切片/切片的后面的值
- **Array 与 Slice 的差异**
**![image.png](https://cdn.nlark.com/yuque/0/2020/png/1732425/1595773658480-9b22f703-4a79-4c1b-84fa-e989c503e20d.png#align=left&display=inline&height=323&margin=%5Bobject%20Object%5D&name=image.png&originHeight=430&originWidth=867&size=56895&status=done&style=none&width=650)**<br />**![image.png](https://cdn.nlark.com/yuque/0/2020/png/1732425/1595773493359-e9e665f7-9847-4fcc-a2bd-f1d6ee14f881.png#align=left&display=inline&height=176&margin=%5Bobject%20Object%5D&name=image.png&originHeight=234&originWidth=853&size=25135&status=done&style=none&width=640)**<br />**![image.png](https://cdn.nlark.com/yuque/0/2020/png/1732425/1595773608762-9bd18cf3-3bb7-49a2-a90e-13181ccafb36.png#align=left&display=inline&height=564&margin=%5Bobject%20Object%5D&name=image.png&originHeight=564&originWidth=615&size=71130&status=done&style=none&width=615)**
**
- Slice定义时不指定长度为可变数组
- Slice的数据结构为`(*ptr,len,cap)`
- Slice不可比较
- Slice的capacity拓展每次增加一倍
<a name="IlEb2"></a>
## 2. Map
```go
func TestMap(t *testing.T) {
// map[keyType]valueType
m1 := map[string]int{"one": 1, "two": 2, "three": 3}
t.Log(m1)
t.Log(m1["three"])
// key 不存在时返回默认初始化值
t.Log(m1["four"])
// 通过一次性给两个变量赋值,确定map中的元素是否存在
if v, ok := m1["four"]; ok {
t.Logf("exits four is %d", v)
} else {
t.Log("four is not exits")
}
//遍历
for k, v := range m1 {
t.Logf("(%s,%d)", k, v)
}
// make(type,capacity)
m2 := make(map[string]string, 16)
t.Log(m2)
}
// map的值类型可以是方法,实现工厂模式
func TestMapWithFunction(t *testing.T) {
// 值类型为 func(op int) int
fund := map[int]func(op int) int{}
fund[1] = func(op int) int {
return op
}
fund[2] = func(op int) int { return op * op }
fund[3] = func(op int) int { return op * op * op }
for _, v := range fund {
t.Log(v(2))
}
}
// map 实现set,利用不存在的value会被初始化为默认值false
func TestMapForSet(t *testing.T) {
mySet := map[int]bool{}
mySet[1] = true
mySet[3] = true
// 判断元素是否存在
existsTest(t, 3, mySet)
// 判断长度
t.Log(len(mySet))
// 删除
delete(mySet, 1)
t.Log(len(mySet))
existsTest(t, 1, mySet)
}
// 注意这种实现set的方式,不要手动的放置false值,否则产生了语义冲突
// 判断元素是否存在
func existsTest(t *testing.T, n int, mySet map[int]bool) {
if mySet[n] {
t.Logf("%d is exists", n)
} else {
t.Logf("%d is not exists", n)
}
}
3. String
// 字符串测试
func TestString(t *testing.T) {
var s string
t.Log(s)
s = "hello 中国"
c := []rune(s)
t.Logf("字符串的字节数:%d, 字符数:%d", len(s), len(c))
for _, v := range s {
t.Logf("char:%[1]c, unicode:%[1]d,%[1]x", v)
}
}
// 字符串转换测试
func TestString2(t *testing.T) {
s := "A,B,C"
parts := strings.Split(s, ",")
for _, part := range parts {
t.Log(part)
}
t.Log(strings.Join(parts, "-"))
ts := strconv.Itoa(10)
t.Log("str" + ts)
if i, err := strconv.Atoi(ts); err == nil {
t.Log(10 + i)
}
}