GO语言 切片 map 字符串 指针 结构体

切片

1.什么是切片

切片本身不拥有任何数据,它们只是对现有数组的引用。

2.切片的定义

1.方式1:由数组切出来:var 变量名 []元素类型 = 数组名[开始值:结束值]
//1.定义数组
var a [8]int=[8]int{1,2,3,4,5,6,7,8}
//2.定义切片,注意[]中没有数字
var b []int=a[2:6]
fmt.Println(b) // [3 4 5 6]

//更多用法,没有步长
var a [8]int=[8]int{1,2,3,4,5,6,7,8}
b:=a[:4]
fmt.Println(b) //[1 2 3 4]

2.方式2:直接定义不赋值。 注意:切片空值是?nil类型
    var a []int
    fmt.Println(a) //[],注意:切片空值是?nil类型
    if a==nil{
        fmt.Println("我是空的")
    }
    //a[0]=10 //报错
    fmt.Println(a)

方式3:make(类型,切片长度,切片容量)
    var a []int=make([]int,3,4)
    fmt.Println(a) //[0 0 0]

    //切片的长度和容量(len     cap:容量)
    var a [8]int=[8]int{1,2,3,4,5,6,7,8}
    var b []int=a[2:6]
    fmt.Println(len(b)) //4
    fmt.Println(cap(b)) //6

    var a []int=make([]int,3,4)
    fmt.Println(a)
    fmt.Println(len(a)) //3
    fmt.Println(cap(a)) //4
3.切片的常用操作
1.切片的长度和容量(len:长度,cap:容量)
    //var a [8]int=[8]int{1,2,3,4,5,6,7,8}
    //var b []int=a[2:6]
    //fmt.Println(len(b)) //4
    //fmt.Println(cap(b)) //6
    
        var a []int=make([]int,3,4)
    fmt.Println(a)
    fmt.Println(len(a)) //3
    fmt.Println(cap(a)) //4

2.切片追加值:append(切片名,值1,值2)
    var a [8]int=[8]int{1,2,3,4,5,6,7,8}
    var b []int=a[2:6]
    b = append(b, 9,10)
    fmt.Println(b) //[3 4 5 6 9 10]
        fmt.Println(a) //[1 2 3 4 5 6 9 10],数组的值也被修改为增加的值
        //当容量到顶,在添加值时
    b = append(b, 11)
    fmt.Println(b) //[3 4 5 6 9 10 11]
    fmt.Println(len(b)) //7
    fmt.Println(cap(b)) //12,容量翻倍
    fmt.Println(a) //[1 2 3 4 5 6 9 10]容量到顶在添加值数组值不在改变

3.修改值:切片名[索引] = 修改值
    var b =make([]int,3,4)
    b[0]=999
    fmt.Println(b) //[999 0 0]
       //超过容量,在修改值时
    var a [6]int=[6]int{1,2,3,4,5,6}
    var b []int=a[1:6]
    fmt.Println(a) //[1 2 3 4 5 6]
    fmt.Println(b) //[2 3 4 5 6]
    b= append(b, 7)
    a[0] = 2
    b[0] = 1
    fmt.Println(a) //[2 2 3 4 5 6]
    fmt.Println(b) //[1 3 4 5 6 7]
总结:追加和修改没超过容量时,一个变另一个跟着变。超过时数组和切片没有关系。

4.切片的函数传递
    var b =make([]int,3,4)
    test(b)
    fmt.Println(b)

 func test(b []int)  {
    b[0]=999
    fmt.Println(b)
}

5.切片的数据结构表示
    var a [][]string=make([][]string,2,3)
    fmt.Println(a) //[[] []]
    fmt.Println(a[0]) //[]

6.多维切片
var a [][]string=make([][]string,2,3)
fmt.Println(a) //[[] []]
fmt.Println(a[0]) //[]
a[0]=make([]string,2,3) //嵌套内的切片在初始化
if a[0]==nil{
   fmt.Println("xxxx")
}

7.多维切片初始化
    var a [][]string=[][]string{{"1","2"},{"3","4"}}
    fmt.Println(a) //[[1 2] [3 4]]
    fmt.Println(len(a)) //2
    fmt.Println(cap(a)) //2
    a[0][1]="999"
    fmt.Println(a) //[[1 999] [3 4]]
8.copy函数:copy(源,目标)
    var a =make([]int,3,10000)
    a[1]=99
    a[2]=888
    fmt.Println(a) //[0 99 888]
    var b =make([]int,2,4)
    fmt.Println(b) //[0 0]
    copy(b,a)
    fmt.Println(b) //[0 99]

3.打散和循环

1.打散   
var a =[]int{1,2,4,} test1(1,2,3,4) test1(a...) //变量名...:相当于打散了 veggies := []string{"potatoes", "tomatoes", "brinjal"} fruits := []string{"oranges", "apples"} food := append(veggies, fruits...) fmt.Println("food:",food) func test1(a ...int) { fmt.Println(a) fmt.Printf("%T",a) }

2.循环
//循环多维切片
pls := [][]string {
{"C", "C++"},
{"JavaScript"},
{"Go", "Rust"},
}
fmt.Println(pls)
for _,v:=range pls {
for _,v1:=range v{
fmt.Println(v1)
}
}

map

1.什么是map

类似于python中的字典,map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值。

2.map的定义和常用方法

1.方式1:var 变量名 map[键值类型]value值类型
        var a map[int]string
    fmt.Println(a) //map[]map的空值是nil类型
        //执行下列if语句
    if a==nil{
        fmt.Println("xxxx")
    }
2. map的初始化
        var a map[int]string=make(map[int]string)
    fmt.Println(a) //map[]此时不是nil类型注意区分
        //不执行下列语句
    if a==nil{
        fmt.Println("xxxxx")
    }
3.赋值:变量名[k] = v,取值:变量名[k],取一个不存在的key值会?返回value值类型的空值
    var a map[int]string=make(map[int]string)
    fmt.Println(a) //map[]
    if a==nil{
        fmt.Println("xxxxx")
    }
        // 赋值
    a[1]="100"
    a[2]="888"
    fmt.Println(a) //map[1:100 2:888]
        //取值
    fmt.Println(a[1]) //100
取值补充:
值,ok:=变量名[k] =>k存在ok为ture,反之为false
    if v,ok:=a[9];ok{
        fmt.Println("=-====",v)
    }else {
        fmt.Println("该值不存在")
    }
4.方式2:定义和初始化
    var a =map[int]string{1:"10",2:"100"}
    fmt.Println(a[1])
5.字典删除元素,内置函数:delete(变量名,k)
    var a =map[int]string{1:"10",2:"100"}
    delete(a,2)
    fmt.Println(a)
6.长度:len(变量名)
var a =map[int]string{1:"10",2:"100"}
fmt.Println(len(a))
7.map循环
var a =map[int]string{1:"10",0:"100",10:"999"}
//map是无序的
    for k,v:=range a{
        fmt.Println(k)
        fmt.Println(v)
    }
8.map的相等性:map 之间不能使用 == 操作符判断,== 只能用来检查 map 是否为 nil,判断两个 map 是否相等的方法是遍历比较两个 map 中的每个元素。我建议你写一段这样的程序实现这个功能
    map1 := map[string]int{
        "one": 1,
        "two": 2,
    }
    
    map2 := map1

    if map1 == map2 {  //报错
    }

字符串

1.什么是字符串

Go 语言中的字符串是一个字节切片。把内容放在双引号""之间,我们可以创建一个字符串。让我们来看一个创建并打印字符串

2.字符串常用方式

1.统计字节数:len(变量名)。统计字符串长度;utf8.RuneCountInString(变量名)
在go种string类型都是utf-8编码
    name := "Hello World刘清政"
    fmt.Println(len(name)) //20
    fmt.Println(utf8.RuneCountInString(name)) //14

2.字符串循环
方式1:按字节循环
    name := "name刘"
    for i:=0;i<len(name);i++{
        fmt.Println(string(name[i]))
        fmt.Printf("%T",name[i])
        fmt.Println()
    }
方式2:按字符循环
        name := "name刘"
    for _,v:=range name{
        fmt.Println(string(v))
        fmt.Printf("%T",v)
        fmt.Println()
    }

指针

1.什么是指针

指针:是一种存储变量内存地址(Memory Address)的变量。

2.指针的类型,地址,反解

1.指针变量的类型为: *值类型(地址关联值的
示例 b := 255 var a *int = &b //应为地址对应的值为255即int类型
2.获取地址:&变量名
示例:获取a的地址
a:=10
b:=&a

3.反解(根据地址获取值):*地址变量名

3.指针的定义和其他使用

1.方式1
a:=10
b:=&a

2.方式2
d:="sss"
var c *string=&d

3.方式3嵌套
a:=10
var b *int =&a
var c **int=&b

4.指针的零值(Zero Value),nil类型
    a := 25
    var b *int //初始化
    if b == nil {
        fmt.Println("b is", b)
        b = &a //赋值
        fmt.Println("b after initialization is", b)
运行结果:
b is <nil>  
b after initialisation is 0x1040a124

5.向函数传递指针参数
    a:=10
    b:=&a
    test6(b)
    fmt.Println(a) //11

func test6(b *int)  {
    //*b 就是 a  a++
    *b++
    fmt.Println(*b) //11

6.不要向函数传递数组的指针,而应该使用切片
        //不建议使用
    //var a [100]int
    //test9(&a)
    //fmt.Println(a)
    
       //推荐使用
    test10(a[:])

func test9(a *[100]int)  {
    (*a)[0]=999
    fmt.Println(a)
}
func test10(a []int)  {
    a[0]=999
    fmt.Println(a)

    fmt.Println(a)
}

结构体

1.什么是结构体

一系列属性的结合体(类似于python中的类)

2.结构体类型和零值

1.结构体和结构体对象的类型就是:结构变量名
2.是结构体属性默认类型的默认值

3.结构体的定义

语法:
type关键字 结构体名字 struct{
属性名1 类型
属性名2 类型
}
方式1:示例
type Person struct {
    name string
    sex ,age int
}

4.结构体实例化与使用

1.定义结构体
type Person struct {
    name string
    sex ,age int
}
2.实例化:结构体名{}
#1.
#实例不初始化
person  :=Person{} //{ 0 0}默认值为各个属性的默认值
#实例不初始化:var 实例化名 结构体类型
var person Person
fmt.Println(person) //{ 0 0}默认值为各个属性的默认值

#2.实例化并赋初始值
方式1:关键字赋值,有的属性可以不传值
var person Person=Person{name:"lqz",sex:1,age:19}
fmt.Println(p)//{lqz,1,19}
方式2:位置赋值,必须全部赋值
 var person Person=Person{"lqz",1,19} 
 fmt.Println(p)//{lqz,1,19}
3.
取值:
实例化名.属性名
改值:
实例化名.属性名 = 新的值

5.匿名结构体

1.指的的是没有名字的结构体
变量定义 = struct {
                 属性1 类型
                 属性2 类型
               }{属性1:值,属性2:值}
2.示例
    a:=struct {
        name string
        age int
    }{"lqz",19}
    fmt.Printf(a.name)

6.结构体指针

4.结构体指针
结构体和结构体指针都可以通过点语法查看值
p:=Person{name:"lqz"}
var pPoint *Person=&p
//fmt.Println(pPoint)
//fmt.Println((*pPoint).name) //lqz
fmt.Println(pPoint.name) //lqz

7.匿名字段

4.匿名字段(用作变量提升)
type Person struct {
    string
    int
}
//p:=Person{"lqz",19} //位置实例化
p:=Person{string:"lqz",int:19} //关键字实例化,关键字为类型名
fmt.Println(p.string)

8.嵌套结构体和变量提升

1.嵌套结构体
//定义被嵌套结构体
type Person struct {
    name string
    sex ,age int
    hobby Hobby //嵌套结构体

}
//定义嵌套结构体
type Hobby struct {
    id int
    name string
}

实例化使用
p:=Person{name:"lqz",hobby:Hobby{10,"篮球"}}
//p:=Person{name:"lqz",hobby:Hobby{id:10,name:"篮球"}}
p.hobby.id=101

2.结构体嵌套+匿名字段
type Person struct {
    name string
    sex ,age int
    Hobby

}
type Hobby struct {
    id int
    //hobbyname string
    name string
}

p:=Person{name:"lqz",Hobby:Hobby{10,"篮球"}}
//取p中的hobbyname两种方式,变量提升过程中如果有重名的,就不提升了
fmt.Println(p.Hobby.hobbyname)
//fmt.Println(p.hobbyname)

posted @ 2019-12-11 23:58  心慌得初夏  阅读(408)  评论(0编辑  收藏  举报
levels of contents