go语言之map集合、字符串、指针

一、map(集合)

  1.定义:

    Map 是一种无序的键值对的集合。通过 key 来快速检索数据,key 类似于索引,指向数据的值。我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为                   Map 是使用 hash 表来实现的。

  2.map的创建

    语法:

//声明变量,默认 map 是 nil
var map1 map[key_data_type]value_data_type

// 使用 make 函数 
map2 := make(map[key_data_type]value_data_type)

    例子:

//通过声明变量
package main

import "fmt"

func main() {
        
    //var a map[键值类型]value值类型
    //map的空值是nil类型
    var a map[int]string
    fmt.Println(a)                   //map[]
    if a==nil{
        fmt.Println("xxx")          //xxx
    }
}

  3、元素操作

    添加:方法与数组的一样

package main

import "fmt"

func main(){

    //map的初始化,创建集合
    var a map[int]string=make(map[int]string)
    //fmt.Println(a)
    //if a==nil{
    //    fmt.Println("hello")
    //}else{
    //    fmt.Println("no hello")           //此时打印这个结果
    //}

    //插入值
    a[1]="cc"
    a[2]="bb"
    //fmt.Println(a)
    //fmt.Println(a[1])

    //取一个不存在的key值会返回value值的值  
    //fmt.Println(a[9])           ////创建一个新的map,判断值是否存在用ok
    var b map[int]int=make(map[int]int)
    b[1]=100
    fmt.Println(b)          //map[1:100]
    fmt.Println(b[9])       //0
    if v,ok:=a[9];ok{                                 //此时通过v来接收a[9]的值,ok作为判断返回true则存在,返回false则不存在
       fmt.Println("=-====",v)
    }else {
       fmt.Println("该值不存在")         //执行这个
    }
    v,ok:=a[1]
    fmt.Println(v)         //cc
    fmt.Println(ok)        //ture

    //定义和初始化的第二种方式
    //var a =map[int]string{1:"10",2:"100"}
    ////a[1]
    //fmt.Println(a[1])
}

    删除:语法是 [delete(map, key)]。这个函数没有返回值。

package main

import (
    "fmt"
)

func main() {
    personSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,
    }

    //给map添加元素
    personSalary["mike"] = 9000

    fmt.Println("map before delete", personSalary)    //map before delete map[jamie:15000 mike:9000 steve:12000]
    delete(personSalary, "steve")
    fmt.Println("map after delete", personSalary)     //map after delete map[jamie:15000 mike:9000]

}

  

  4、获取map的长度:len(map名),长度为k:v键值对的个数

 

  5、map同样也是引用数据类型

    和 [slices]切片类似,map 也是引用类型。当 map 被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量。

package main
import "fmt"
func main(){
    //Map 是引用类型
    var a =map[int]string{1:"10",2:"100"}
    test1(a)
    fmt.Println(a)             //上面执行了函数test1(),数据已经被修改,map[1:888 2:100]
    }

func test1(a map[int]string)  {
    a[1]="888"
    fmt.Println(a)         //map[1:888 2:100]
} 

  

  6、map的相等性

    map 之间不能使用 == 操作符判断,== 只能用来检查 map 是否为 nil

package main

func main(){

    //map1 := map[string]int{
    //    "one": 1,
    //    "two": 2,
    //}

    //map2 := map1

    //if map1 == map2 {  //报错
    //}

    //map循环出所有元素
    //var a =map[int]string{1:"10",0:"100",10:"999"}
    ////for i:=0;i<=len(a);i++{
    ////   fmt.Println(a[i])
    ////}
    ////map是无序的
    //for k,v:=range a{
    //  fmt.Println(k)
    //  fmt.Println(v)
    //}

}

 

二、字符串

  1.定义

    Go 语言中的字符串是一个字节切片。Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。go中的string字符串的形式都是以utf-8的形式存入内存中,而其他语言以Unicode万国码形式。

    字符串是不可变的,Go 中的字符串是不可变的。一旦一个字符串被创建,那么它将无法被修改。字符只能读取,不支持修改。

  2、编码方式介绍

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {

    name := "Hello World老虎"
    //name:="赵"
    //字符串长度,len统计字节数
    //在go种string类型都是utf-8编码
    fmt.Println(len(name))                 //17
    fmt.Println(utf8.RuneCountInString(name))      //13,
    //unicode是一个字符编码对照表

    //循环
    //字符串是个只读切片
    //name := "name李"
    //for i:=0;i<len(name);i++{
    //    fmt.Println(string(name[i]))
    //    fmt.Printf("%T",name[i])
    //    fmt.Println()
    //}

    //for _,v:=range name{
    //    fmt.Println(string(v))
    //    fmt.Printf("%T",v)
    //    fmt.Println()
    //}

    //name := "name李"
    //name[0]=99
    //fmt.Println(name[0])
    //fmt.Println(string(name[0]))

    byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}// 打印的是字节数
    str := string(byteSlice)
    a:=len(str)                
    b:=utf8.RuneCountInString(str)
    fmt.Println(b)          //4
    fmt.Println(a)          //5
    fmt.Println(str)         //Café
}

 

三、指针

  1.定义

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

  2.类型声明

    

指针变量的类型为 *T,该指针指向一个 T 类型的变量。

 //&取地址符号
 //* 放在类型旁边,表示指向这个类型的指针
 //* 放在变量旁边,取出指针指向的具体值。表示解引用(反解)

  3、演示

import "fmt"
func main() {
    //&取地址符号
    //* 放在类型旁边,表示指向这个类型的指针
    //* 放在变量旁边,表示解引用(反解)
    a:=10
    //b就是一个指针 指向int类型的指针
    //b:=&a
    //d:="sss"
    //var c *string=&d
    var b *int =&a
    fmt.Println(b)         //0xc00000a0b0,此时b就是指针,指向a的内存地址
    fmt.Println(*b)        //把b对应的值给取出来,10
    c:=&b
    //var c **int=&b        //指向int类型的指针
    fmt.Println(*(*c))  //10,此时*放在变量旁边,*c解开b的内存地址,*(*c)解出值
}

  4、指针的零值:零值是 nil

package main
import "fmt"
func main(){
   //指针的零值(Zero Value),nil类型
    var a *int
    fmt.Println(a)        //nil
}

  5、向函数传递指针参数

package main

import "fmt"

func change(val *int)  {
    *val = 55              //因为val类型为指针,需要加*反解为变量值
}
func main()  {
    a:=58
    fmt.Println(a)       //58
    b:=&a
    change(b)            //此时给指针变量b传值55
    fmt.Println(a)       //55
}

 

注意:不要向函数传递数组的指针,而应该使用切片。假如我们想要在函数内修改一个数组,并希望调用函数的地方也能得到修改后的数组,一种解决方案是把一个指向数组的指针传递给这个函数。

package main

import "fmt"

func main() {

    //不要向函数传递数组的指针,而应该使用切片
    var a [4]int
    test9(&a)
    fmt.Println(a)         //&[999 0 0 0]
    test10(a[:])
    fmt.Println(a)        //[999 0 0 0]
    //Go 不支持指针运算
}

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

 

GO不支持指针运算

//下面这种是不允许的

package main

func main() {  
    b := [...]int{109, 110, 111}
    p := &b
    p++
}

 

posted @ 2022-03-27 17:24  新入世界的小白  阅读(302)  评论(0)    收藏  举报