go基础编程day4切片slice与map

2018-06-21  本文已影响0人  james_chang

切片slice

package main

import (
    "fmt"
)

// 创建slice
func main() {
    // 声明空slice
    var s1 []int
    fmt.Println(s1) // []
    // 切片生成slice
    a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
    s2 := a[5:]
    fmt.Println(s2, len(s2), cap(s2)) // [6 7 8 9 0] 5 5
    // make生成slice
    s3 := make([]int, 3, 10)
    fmt.Println(s3, len(s3), cap(s3)) // [0 0 0] 3 10
}

reslice

如果是切片生成的slice则要注意几点:

package main

import (
    "fmt"
)

func main() {
    // 切片生成slice
    a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
    s2 := a[3:5]
    fmt.Println(s2, len(s2), cap(s2)) // [4 5] 2 7
    // 对长度为2的s2进行切片取长度外的值依然能取到
    s3 := s2[3:5]
    fmt.Println(s3) // [7 8]
}

这里要明确的是s2取到的slice虽然长度只有2但是他的最大容量是到原数组尾部的,并且,slice是引用的一个地址,所以能取到后面的值

append

package main

import (
    "fmt"
)

func main() {
    s1 := make([]int, 3, 6)
    fmt.Printf("%p\n", s1) // 0xc420084030
    s1 = append(s1, 1, 2, 3)
    fmt.Printf("%p\n", s1) // 0xc420084030
    s1 = append(s1, 1, 2, 3)
    // 第三次内存地址发生改变,超出原有容量
    fmt.Printf("%p\n", s1) // 0xc42007a060
}
package main

import (
    "fmt"
)

func main() {
    a := []int{1, 2, 3, 4, 5}
    s1 := a[2:5]
    s2 := a[1:3]
    fmt.Println(s1, s2)
    s1[0] = 9
    // 改变了s1,s1,s2和a都改变了
    fmt.Println(s1, s2, a)
}

copy

package main

import (
    "fmt"
)

func main() {
    s1 := make([]int, 5, 10)
    s2 := []int{7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1}
    // 第一个参数是copy到的目标,第二个是被copy的
    // 这里是将s2 copy到 s1
    copy(s1, s2)
    fmt.Println(s1) // [7 8 9 4 5 6]
}

/*
总结
copy最后的长度为copy目标的长度(非容量)
copy到对象的长度能容纳多少就会容纳多少
如果被copy的对象长度较小,按照顺序copy,剩下的原封不动
*/

map(类似字典)

package main

import (
    "fmt"
)

func main() {
    // 第一种方式
    var m map[int]string
    m = map[int]string{}
    fmt.Println(m)
    // 第二种方式
    var m1 map[int]string = make(map[int]string)
    fmt.Println(m1)
    // 第三种其实就是去掉第二种中多余的部分
    var m2 = make(map[int]string)
    fmt.Println(m2)
    // 简洁方式
    m3 := make(map[int]string)
    fmt.Println(m3)
}

增删

package main

import (
    "fmt"
)

func main() {
    m := make(map[int]string)
    m[1] = "ok"
    a:=m[1]
    b:= m[2]
    fmt.Println(m) // map[1:ok]
    fmt.Println(a) // ok
    fmt.Println(b) // 此处取出的为空
    delete(m,1)
    fmt.Println(m[1]) // 删除了
}

复杂map

package main

import "fmt"

func main() {
    m := make(map[int]map[int]string)
    // 如果map内层还有map,内层的map也要初始化
        // 如果不初始化则取出的为空字符,并且赋值的时候报错
    m[1] = make(map[int]string)
    m[1][1] = "ok"
    a := m[1][1]
    fmt.Println(a) // ok
}

如何知道内层map是否已经初始化了(防止赋值的时候报错)

package main

import "fmt"

func main() {
    m := make(map[int]map[int]string)
    a := m[1][1]
    fmt.Println(a) // 此时输出为空字符串
    b, ok := m[1][1]
    fmt.Println(b, ok) // 空字符串和false
}
// 这个时候就可以加个判断,如果第二个返回值为false就说明没有初始化,否则已经初始化了

对slice和map进行迭代操作

对元素为map的slice进行迭代的时候,获取到的v是值的copy,所以不能真正修改slice中map的值这个时候迭代k通过k来直接修改map

// 迭代一个内容为map的slice
func main() {
    // 5个map
    sm := make([]map[int]string, 5)
    // 想真正修改被迭代对象的值,需要迭代索引,利用索引直接修改迭代对象
    for i := range sm {
        sm[i] = make(map[int]string, 1)
        sm[i][1] = "ok"
        fmt.Println(sm[i])
    }
    fmt.Println(sm)


    /*
    map[1:ok]
    map[1:ok]
    map[1:ok]
    map[1:ok]
    map[1:ok]
    [map[1:ok] map[1:ok] map[1:ok] map[1:ok] map[1:ok]]
    
    */
}

map是无序的,但是可以通过key进行间接排序:排序k,通过有序的k来取map中的v

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[int]string{1: "a", 2: "b", 3: "c", 4: "d", 5: "e"}
    s := make([]int, len(m))
    i := 0
    // 将map中的k存在slice中
    for k := range m {
        s[i] = k
        i++
    }
    // 排序slice
    sort.Ints(s)
    fmt.Println(s)
    // 完成了对k的排序之后就可以有序取map中的值
}

map k-v调换位置

package main

import (
    "fmt"
)

func main() {
    m1 := map[int]string{1: "a", 2: "b", 3: "c", 4: "d", 5: "e"}
    m2 := make(map[string]int)
    fmt.Println(m1)
    for k,v := range m1{
        m2[v] = k
    }
    fmt.Println(m2)
}
上一篇下一篇

猜你喜欢

热点阅读