一、Go语言上手

2-1 go发展历程、企业应用、语言特性

go编程语言特性:
自动垃圾回收、函数多返回值、错误处理、闭包与匿名函数、接口与类型、并发编程、反射、内置丰富类型

Mac下go安装与环境变量设置: 
在网站 https://golang.google.cn/dl/ 下载 .pkg 安装

GOROOT=/usr/local/go #默认的golang安装路径
GOPATH=$HOME/gopath #默认安装包的路径(源码包, 进行业务的开发, 把源码放到gopath当中, 以及第三方库或从第三方网站下载的库也会安装到默认的gopath当中)
    cd $GOPATH目录下有三个文件bin、pkg、src
        bin: 用于生成可执行文件.(存放一些之前安装到这里的项目)
        pkg: 用于生成的第三方扩展库(.a文件)
        src: 存放的源码文件(自己的项目、第三方库项目)

GOBIN=$GOPATH/bin #是我们go执行go install编译之后存在的一个路径, 一般是放在$GOPATH下的bin目录下

PATH=$PATH:$GOROOT/bin:$GOPATH/bin #  PATH是系统内建的, 被称为系统的环境变量. 比如去执行安装软件它的一个可执行程序, 当我们设置了PATH, 比如说将对应的GOBIN把它环境变量配置PATH当中, 我们无论在哪个路径下面都会执行.
GOPATH把它加入到我们的环境变量当中,然后保存. 执行$ source ~/.bash_profile 命令, 让它重新生效.
通过命令 $ go env #来查看本机go语言的安装情况

3-1 变量概述、变量格式化输出

///格式化输出的所有格式:

  //通用:
    %v  值的默认格式表示
    %+v 类似%v, 但输出结构体时会添加字段名
    %#v 值的go语法表示
    %T  值的类型的Go语法表示
    %%  百分号

  //布尔值:
    %t  单词true或false

    //进制数:
        %b  表示二进制
        %c  该值对应的Unicode码值
        %d  表示十进制
        %o  表示为8进制
        %q  该值对应的单引号括起来的go语法字符串面值, 必要时会采用安全的转义表示
        %x  表示为十六进制, 使用a-f
        %X  表示为十六进制, 使用A-F
        %U  表示为Unicode格式, 比如U+1234,等价于"U+%04X"

    //浮点数与复数的两个组分:
        %b  无小数部分、二进制指数的科学计数法, 如-123456p-78; 参见strconv.FormatFloat
        %e  科学计数法, 如-1234.456e+78
        %E  科学计数法, 如-1234.456E+78
        %f  有小数部分但无指数部分, 如123.456
        %F  等价于%f
    %g  根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
    %G  根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)

  //字符串和[]byte:
    %s  直接输出字符串或者[]byte
    %q  该值对应的双引号括起来的go语法字符串字面值, 必要时会采用安全的转义表示
    %x  每个字节用两个字符十六进制数表示(使用a-f)
    %X  每个字节用两个字符十六进制数表示(使用A-F)

  //指针:
    %p  表示为十六进制, 并加上前导的0x

3-2 变量的使用、变量的内存布局

package main
import "fmt"

///声明多个全局变量
var (
    variablesx int
    slicex []int
    interfacex interface{}
)

func main() {
    /// 局部变量的方法:
    //方式一
    var variables1 int
    //方式二: 简短声明. 只能在函数内部这样声明, 在函数外部无法这样声明使用.
    variables2 := "我是老大"
    //方式三:
    var variables3 = 100
    //方式四: 一次性申请多个变量
    var variables4,variables5,variables6,variables7 = 1,"我是土豆",3.14,true
    fmt.Println(variables1,variables2,variables3,variables4,variables5,variables6,variables7)

    //简单的变量值交换
    var i = 100
    var j = 200
    i,j = j,i
    fmt.Println(i,j)

    // _, x := 22, 100 //_声明的变量, 会被丢弃.

    //定义变量注意事项:
    //go语言当中大写开头的变量, 是可以被其他包读取的使用的, 相当于其他语言的public权限; 变量小写表示只能被本包使用.
    var Varaibles = 19
}

3-3 常量概述、常量的使用、常量的应用场景

func main() {
    // 常量 const
    const constVariables1 float64 = 3.1415926
    const constVariables2, constVariables3 = 100, "你好少年"
    fmt.Println(constVariables1,constVariables2,constVariables3)

    // iota比较特殊, 编译器会修改它的值, 它会在每个const关键字出现时重置为零, 在下一个const出现之前, 每个iota+1
    const (
        iotaVariables1 = iota //0
        iotaVariables2 = iota //1
        iotaVariables3 = iota //2
    )
    const  iotaVariables = iota //0
    fmt.Println(iotaVariables1,iotaVariables2,iotaVariables3, iotaVariables)

    //常量的应用场景:
    //比如用const和iota来代替枚举做声明, 表示一周
    const (
        Monday = iota
        Tuesday
        Wednesday
        Thursday
        Friday
        Saturday
        Sunday
    )
    fmt.Println(Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday)//0 1 2 3 4 5 6

    const (
        iotaVariables8,iotaVariables9,iotaVariables10 = iota,iota,iota// 0 0 0
    )
    const (
        iotaVariables11 = iota //0
        iotaVariables12 = "Bobo" //Bobo
        iotaVariables13 = iota //2
    )
    fmt.Println(iotaVariables8,iotaVariables9,iotaVariables10,iotaVariables11,iotaVariables12,iotaVariables13)//0 0 0 0 Bobo 2
}

4-1 数值类型概述、不同数值类型表示范围、数据类型的使用

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    /* 有符号位
    int8    占1个字节   数值范围-2^7到2^7-1
    int16   占2个字节   -2^15到2^15-1
    int32   占4个字节   -2^31到2^31-1
    int64   占8个字节   -2^63到2^63-1
    */
    /* 无符号位
    uint8   占1个字节   数值范围0到2^8-1
    uint16  占2个字节   0到2^16-1
    uint32  占4个字节   0到2^32-1
    uint64  占8个字节   0到2^64-1
    */

    var intVariables1 = 100 //int
    intVariables2 := 200 //int
    fmt.Printf("intVariables1=%T,intVariables2=%T\n",intVariables1,intVariables2)//intVariables1=int,intVariables2=int

    var intVariables3 int32 //int32
    intVariables := 126 //int
    intVariables3 = int32(intVariables)// int转换为int32
    fmt.Printf("intVariables3=%T\n",intVariables3)//intVariables3=int32

    //查看占用空间大小(字节数)
    var intVariables4 int64 = 123456789
    fmt.Println(unsafe.Sizeof(intVariables4)) // 8 (占用8个字节)
}

/// ctrl + R 运行程序

4-2 浮点概述、浮点类型的使用、复数的使用

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    /* 有符号位
    float32 占4个字节
    float64 占8个字节 (默认类型)
    */
    //1.以十进制的形式来展示
    var floatVariables1 = 3.141592653
    fmt.Printf("floatVariables1的类型=%T, 占用的字节大小=%d \n", floatVariables1,unsafe.Sizeof(floatVariables1))//floatVariables1的类型=float64, 占用的字节大小=8

    //2.以科学计数法来展示
    floatVariables3 := 3.1415926e2 // 表示3.1415926乘以10的2次方
    floatVariables4 := 3.1415926e-2 // 表示3.1415926乘以10的-2次方
    fmt.Println(floatVariables3,floatVariables4)//314.15926 0.031415926

    ///复数: 主要由浮点型表示. 实数"+"虚数i
    /*
    complex64   由32位实数+32位虚数组成, i是虚数的单位
    complex128  由64位实数+64位虚数组成, i是虚数的单位 (默认类型)
    */
    //复数定义:
    var complexVariables1 complex64
    complexVariables1 = 3.14+12i//复数的应用场景: 一元二次方程
    complexVariables2 := complex(3.14,12)//实数部分是3.14, 虚数部分是12
    fmt.Printf("complexVariables1的类型=%T,值=%v\n",complexVariables1,complexVariables1)//complexVariables1的类型=complex64,值=(3.14+12i)
    fmt.Printf("complexVariables2的类型=%T,值=%v\n",complexVariables2,complexVariables2)//complexVariables2的类型=complex128,值=(3.14+12i)

    //分别打印实数部分和虚数部分
    fmt.Println(real(complexVariables1),imag(complexVariables1))//3.14 12
}

4-3 字符概述、使用

package main

import "fmt"

func main() {
    /*
    字符:
    byte(uint8) //占用一个字节, 无符号, 代表一个utf-8的无符号字节值
    rune 代表Unicode字符 //rune实质上是int32的别名, 代表utf-8的一个字符

    字符转换成-->ASCII码值-->再转换成二进制
    二进制-> ASCII码值-->字符

    字符可以参与运算
    */
    var charVariables1 byte = '0'
    charVariables2 := '铁'
    fmt.Printf("charVariables2=%c, charVariables2的类型:%T\n",charVariables2, charVariables2)//charVariables2=铁, charVariables2的类型:int32
    fmt.Printf("charVariables1 = %d, charVariables2=%d\n",charVariables1,charVariables2)//charVariables1 = 48, charVariables2=38081

    variables := 'a' //对应的编码值
    fmt.Printf("加和=%d,a的编码值=%d\n",100+variables,variables)//加和=197,a的编码值=97
}

4-4 字符串概述、字符串使用、字符串遍历、中文字符串的处理

package main

import "fmt"

func main() {
    /*
    字符串:string, 采用的是utf-8编码
    */
    var stringVariables1 string
    stringVariables1 = "hello 拿小铁\n"
    var stringVariables2 = `
a
aa
aaa
`
    fmt.Printf("stringVariables1=%T,stringVariables2=%T\n",stringVariables1,stringVariables2)//stringVariables1=string,stringVariables2=string
    fmt.Printf("stringVariables1=%v,stringVariables2=%v",stringVariables1,stringVariables2)
    //打印字符串长度
    fmt.Println(len(stringVariables2))//10
    //字符串拼接
    fmt.Println("hello"+"拿小铁")
    //遍历字符串(以字节的方式遍历)
    var stringVariables3 = "hello dbc, 我是拿小铁"
    stringVariables3Len := len(stringVariables3)
    for index := 0; index <stringVariables3Len; index++ {
        fmt.Printf("%s--编码码=%d, 值=%c\n",stringVariables3,stringVariables3[index],stringVariables3[index])
    }

    ///中文字符串的处理
    // 遍历字符串:
    for _, value := range  stringVariables3{
        // 此时的value是rune int32
        fmt.Printf("%s--编码码=%d, 值=%c, 类型=%T\n",stringVariables3,value,value,value)
    }
}

4-5 布尔类型概述、使用

package main

import "fmt"

func main() {
    /*
    bool true false
    */
    var boolVaraibles1 bool
    boolVaraibles1 = true
    boolVaraibles2 := (true==false)
    fmt.Println(boolVaraibles1,boolVaraibles2)

    //bool 类型不接受其他类型的赋值, 不支持自定义类型转换
    if 3==4 {
        fmt.Println("false")
    }else {
        fmt.Println("true")
    }
    fmt.Println(!true,!false,!!true)// false true true

    /// go语言不支持 ===
}

5-1 指针概述、指针使用、指针内存布局分析

package main

import "fmt"

func main() {
    /*指针:
    指针主要用于管理内存.
    如果内存管理不当就会出现指针的混乱传递, 比如某一个内存空间已经释放了, 而另一个程序还在使用这个内存, 就会导致内存泄漏. 也野指针.
    指针也是一个变量, 存储的是另一个变量的内存地址.
    指针变量的值是一个地址
    */

    /// 指针的使用与内存布局
    var intVariables int = 100
    //打印指针
    fmt.Printf("intVariables的值=%d,地址=%v\n",intVariables,&intVariables)
    //定义指针, 取内存地址
    var pointerVariables *int = &intVariables
    fmt.Printf("pointerVariables的值=%v,地址=%v\n",pointerVariables,&pointerVariables)
    /*
        变量名             变量值         内存地址
        intVariables        100             0xc00001c090
        pointerVariables    0xc00001c090    0xc00000e030
    */
}

5-2 指针内存布局分析、指针作用、指针运算与多级指针

package main

import "fmt"

func main() {
    /*指针的作用:
  一、节省内存空间, 提高程序执行效率
  二、间接访问与修改变量的值
  */

    /// 指针的使用与内存布局
    var intVariables int = 100
    //定义指针, 取内存地址
    var pointerVariables *int = &intVariables

    //获取到指针指向的值, 并修改
    fmt.Println(intVariables)
    *pointerVariables = 200
    fmt.Println(intVariables)

    // 通过指针获取变量的值
    var variables2 int = 123 // 定义变量
    var pointerVariables2 *int = &variables2 //获取指针(内存地址)
    fmt.Println(*pointerVariables2,variables2)

    /*
    值类型: 整形, 浮点型, bool, array, string. 值类型一般在栈中分配内存
    引用类型: 指针, slice, map, chan, interface. 引用类型一般在堆中分配内存
    */

    //指针可以指向另一个指针, 不推荐这样做

    //当我们定义一个指针的时候, 并没有分配任何变量, 那么它的值默认为nil
    var pointer1 *int
    *pointer1 = 100 //报错: 无效的内存地址
}

5-3 数组概述、内存布局分析、数组的使用

package main

import "fmt"

func main() {
    /*数组
        数组的下标, 从0开始, 数组的长度通过len()获取
        数组是长度固定的数据类型, 元素的类型都是一样的, 数组在内存当中是连续的存储空间, 可以有效的提升CPU的执行效率
        变量或数组在定义时, 如果没有赋值, 会有默认值(零值)
            整形: 默认值0
            字符串: 默认值""
            bool: 默认值false
    */
    // 数组的定义方式一:
    var arrayVariables [10]int
    arrayVariables[0] = 100
    arrayVariables[3] = 200
    fmt.Println(arrayVariables)//[100 0 0 200 0 0 0 0 0 0]

    // 数组在内存当中是连续的存储空间
    var arrayVariables2 [5] int = [5]int{1,2,3,4,5}
    var length = len(arrayVariables2)
    for i:=0; i<length; i++ {
        fmt.Printf("arrayVariables2[%d]=%d,地址=%p\n",i,arrayVariables2[i],&arrayVariables2[i])
    }

    /// 数组定义方式2
    // 注意:在go语言中 [10]int 与 [5]int 被认为是不同的类型
    // 数组的长度是数组的组成部分
    arrayVariables3 := [...]int{1,2,3,4,5}
    fmt.Println(arrayVariables3,len(arrayVariables3))

    //数组的定义方式3: 指定下标的值
    arrayVariables4 := [...]int{100:200,300:500}
    fmt.Println(len(arrayVariables4))// 301
}

5-4 数组的使用、数组作为函数参数意义、二维数组与多维数组

package main

import "fmt"

func main() {

    //在go语言中数组是值类型
    arrayVariables5 := [10]int{1,2,3}
    fmt.Println(arrayVariables5)
    changeArr(arrayVariables5)
    fmt.Println(arrayVariables5)

    // 通过指针的方式来改变数组的元素
    changeArrByPointer(&arrayVariables5)
    fmt.Println(arrayVariables5)

    //二维数组
    var arrayVariables8 [4][2]int //数组中有4个数组元素, 每个数组元素包含两个int元素
    fmt.Println(arrayVariables8) //[[0 0] [0 0] [0 0] [0 0]]
    //使用字面量进行初始化二维数组
    arrayVariables9 := [4][2]int{{1,2},{3,4},{5,6},{7,8}}
    fmt.Println(arrayVariables9)// [[1 2] [3 4] [5 6] [7 8]]
    //指定下标初始化二维数组
    arrayVariables10 := [4][2]int{1:{10,9}}
    fmt.Println(arrayVariables10)// [[0 0] [10 9] [0 0] [0 0]]

    //多维数组
    var arrayVariables11 [4][3][2]int = [4][3][2]int{}
    fmt.Println(arrayVariables11)
}

// 成功的改变了数组的值✅
func changeArrByPointer(arr *[10]int)  {
    (*arr)[0] = 100
}

// 这样并不会改变数组的内容❌
func changeArr(arr [10]int)  {
    arr[0] = 100
}

5-5 切片概述、切片使用、切片与数组内存布局分析

/*切片是什么?
  一种数据结构, 便于使用与管理我们的数据集合.
  按需自动增长, 动态数组(通过append来完成)
  底层指向的是数组
  内存当中是连续的存储空间, 可以有效的提升CPU的执行效率
  引用类型
*/
package main

import "fmt"

func main() {
    /*切片 slice
        切片又被称为动态数组, 切片长度是可以改变的
        切片由三个部分组成: 指向底层数组的指针, 切片的元素个数(长度len), 切片的容量cap.
        切片是引用类型
        遍历方式和数组类似, 都是通过for, for range
    */
    //切片的定义
    var sliceVariables []int
    //定义一个数组
    arrayVariables := [...]int{12,21,23,55,98,2}
    for i := 0; i < len(arrayVariables); i++ {
        fmt.Printf("arrayVariables[%d]=%d, 地址=%p\n",i,arrayVariables[i],&arrayVariables[i])
    }
    //通过切片去引用数组
    sliceVariables = arrayVariables[:]
    for i := 0; i < len(sliceVariables); i++ {
        fmt.Printf("sliceVariables[%d]=%d, 地址=%p\n",i,sliceVariables[i],&sliceVariables[i])
    }// 切片元素中元素的地址值 与 数组中元素的地址值一直

    //切片指向的是底层数组
    var sliceVariables2 []int
    sliceVariables2 = arrayVariables[1:3] //引用数组的第2-4个元素
    fmt.Println(sliceVariables2)// [21 23]
    for i := 0; i < len(sliceVariables2); i++ {
        fmt.Printf("sliceVariables2[%d]=%d, 地址=%p\n",i,sliceVariables2[i],&sliceVariables2[i])
    }

    //通过切片改变对应的值
    sliceVariables2[0] = 100 //切片对应的是底层数组, 改变的是底层数组的元素的值
    fmt.Println(sliceVariables)// [12 100 23 55 98 2]
    fmt.Println(sliceVariables2)// [100 23]
}

5-6 切片作为函数参数

package main

import "fmt"

func main() {
    //切片的第二种定义方式: make
    var sliceVariable3 []int = make([]int,5,6)//长度是5, 容量为6
    fmt.Printf("sliceVariables3的长度=%d,容量=%d,切片指向的底层数组的地址=%p,切片自己的地址=%p\n",len(sliceVariable3),cap(sliceVariable3),sliceVariable3,&sliceVariable3)//sliceVariables3的长度=5,容量=6,切片指向的底层数组的地址=0xc00010c060,切片自己的地址=0xc000120048

    //切片的追加: append
    sliceVariable3 =  append(sliceVariable3, 7)
    fmt.Printf("第一次追加sliceVariables3的长度=%d,容量=%d,切片指向的底层数组的地址=%p,切片自己的地址=%p\n",len(sliceVariable3),cap(sliceVariable3),sliceVariable3,&sliceVariable3)

    sliceVariable3 =  append(sliceVariable3, 8)
    fmt.Printf("第二次追加sliceVariables3的长度=%d,容量=%d,切片指向的底层数组的地址=%p,切片自己的地址=%p\n",len(sliceVariable3),cap(sliceVariable3),sliceVariable3,&sliceVariable3)

    //切片的copy
    sliceVariable4 := []int{1,2,3,4,5}
    sliceVariables5 := make([]int, 10)
    fmt.Println(sliceVariable4)// [1 2 3 4 5]
    fmt.Println(sliceVariables5)// [0 0 0 0 0 0 0 0 0 0]
    copy(sliceVariables5,sliceVariable4)//将sliceVariables4 的内容拷贝到 sliceVariables5当中
    fmt.Println(sliceVariable4)// [1 2 3 4 5]
    fmt.Println(sliceVariables5)// [1 2 3 4 5 0 0 0 0 0]

    sliceVariables6 := make([]int,1)
    copy(sliceVariables6,sliceVariable4)
    fmt.Println(sliceVariable4)// [1 2 3 4 5]
    fmt.Println(sliceVariables6)// [1]

    /// 切片是引用类型
    fmt.Println(sliceVariables5)// [1 2 3 4 5 0 0 0 0 0]
    changeSlice(sliceVariables5)
    fmt.Println(sliceVariables5)// [100 2 3 4 5 0 0 0 0 0]
}

func changeSlice(slice []int)  {
    slice[0] = 100
}

5-7 map概述、定义与使用方式、map内存布局分析

package main

import "fmt"

func main() {
    /*
    map 也被称为集合, 这种数据类型是一个无序的键值对
    键值对: map[key] = value
    通过散列表函数对我们的map进行存储
    */

    // 1.map的声明
    var mapVariabels1 map[string]string
    // 2.map的定义--make
    mapVariabels1 = make(map[string]string)
    mapVariabels1["Monday"] = "周一"
    mapVariabels1["Tuesday"] = "周二"
    fmt.Println(mapVariabels1)//map[Mondy:周一 Tuesday:周二]

    // map这里的key是唯一的, 不能重复
    mapVariabels1["Monday"] = "大周一"
    fmt.Println(mapVariabels1)// map[Monday:大周一 Tuesday:周二]

    // map len
    fmt.Println(len(mapVariabels1)) //2

    // 声明的时候同时赋值
    var mapVariable2 = map[string]int{
        "Monday":1,"Tuesday":2,
    }
    fmt.Println(mapVariable2)// map[Monday:1 Tuesday:2]

    // 通过 := 和make 来声明map
    mapVariables3 := make(map[string]int)
    mapVariables3["Monday"] = 100
    fmt.Println(mapVariables3) //map[Monday:100]
}

5-8 map的使用方式、遍历、有序输出

package main

import (
    "fmt"
    "sort"
)

func main() {

    //切片和函数不可以作为map的key
    //mapVariables4 := map[[]string]int{}

    mapVariables5 := map[int][]string{}
    var sliceString []string
    sliceString = make([]string,3)
    sliceString[0] = "拿小铁"
    sliceString[1] = "golang"
    sliceString[2] = "go瑜伽课"
    mapVariables5[0] = sliceString
    fmt.Println(mapVariables5)//map[0:[拿小铁 golang go瑜伽课]]

    //⚠️只声明没有make, 报错
    //var mapVariables6 map[string]string
    //mapVariables6["hello"] = "拿小铁"
    //fmt.Println(mapVariables6)// panic: assignment to entry in nil map
    
    //map是一个引用类型
    fmt.Printf("mapVariables3['Monday']在函数调用之前的值:%v\n",mapVariables3["Monday"])
    changeMap(mapVariables3)
    fmt.Printf("mapVariables3['Monday']在函数调用之后的值:%v\n",mapVariables3["Monday"])

    // 如何来对map的key进行顺序输出, for range
    var sortKeys []string //sp1.定义切片
    for key,_ := range mapVariables3{
        sortKeys = append(sortKeys, key)//sp2.把map的key保存到切片中
    }
    fmt.Printf("排序前sortkeys的值=%v\n",sortKeys)
    // sort: 将一个切片进行排序, 按照增长的方式
    sort.Strings(sortKeys)//sp3.按照ASSIC码值进行排序
    fmt.Printf("排序后sortkeys的值=%v\n",sortKeys)
    for i := 0; i < len(sortKeys); i++ {
         fmt.Printf("mapVairables3[%s]=%d\n",sortKeys[i],mapVariables3[sortKeys[i]])
    }
}

func changeMap(mapVariables map[string]int)  {
    mapVariables["Monday"] = 888
}

5-9 结构体作为map的值、map切片

package main

import (
    "fmt"
    "sort"
)

func main() {
    
    //结构体和C语言的类似, 需求: 定一个结构体, 作为map的值
    type course struct {
        courseName string //课程名称
        courseTime float32 //课程时长 单位分钟
        courseTeacher string //课程讲师
    }
    //定义结构体变量
    course1 := course{
        "go瑜伽课",300.3,"拿小铁",
    }
    course2 := course{
        courseTeacher: "胡歌",
        courseTime: 100.2,
        courseName: "如何变帅?",
    }
    courser := make(map[string]course)
    courser["go"] = course1
    courser["美容"] = course2
    fmt.Println(courser)//map[go:{go瑜伽课 300.3 拿小铁} 美容:{如何变帅? 100.2 胡歌}]

    /// 判断一个key在我们的map当中是否存在?
    //方式一:
    value,ok := courser["go"]
    if ok {
        fmt.Println(value)
    }else {
        fmt.Println("no value")
    }
    //方式二:
    if value,ok := courser["go"];ok{
        fmt.Println(value)
    }

    ///map切片(map+切片): 切片也可以把map作为值来使用, 长度是可以动态改变的
    //interface{} 可以把它当做万能类型
    var mapVariables6 []map[string]interface{} // 可以把整型、浮点型、字符串等赋值给interface{}
    mapVariables6 = make([]map[string]interface{},2)//定义切片, 含两个map
    mapVariables6[0] = make(map[string]interface{},2)//定义map1
    mapVariables6[0]["name"] = "拿小铁"
    mapVariables6[0]["age"] = 18

    mapVariables6[1] = make(map[string]interface{},2)//定义map2
    mapVariables6[1]["name"] = "胡歌"
    mapVariables6[1]["age"] = 16
    fmt.Println(mapVariables6)
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容