go 数据类型

go 语言将数据类型分为四类,包括:基础类型,复合类型,引用类型和接口类型,其中

go 语言的引用类型包括:指针、切片、字典、函数、通道

go 语言的基本类型包括:数字、字符串、布尔、数组 及 接口类型

go 语言的复合数据类型:数组、结构体

int和uint的区别

int8的范围就是-128~127 有符号

uint的范围就是0~255 无符号

a := byte(255) //11111111 这是byte的极限, 因为 a := byte(256)//越界报错, 0~255正好256个数,不能再高了

b := uint8(255) //11111111 这是uint8的极限,因为 c := uint8(256)//越界报错,0~255正好256个数,不能再高了

c := int8(127) //01111111 这是int8的极限, 因为 b := int8(128)//越界报错, 0~127正好128个数,所以int8的极限只是256的一半

d := int8(a) //11111111 打印出来则是-0000001,int8(128)、int8(255)、int8(byte(255))都报错越界,因为int极限是127,但是却可以写:int8(a),第一位拿来当符号了

e := int8(c) //01111111 打印出来还是01111111

数组定义

    var arr0 = [5]int{1, 2, 3}
    for _, value := range arr0 {
        fmt.Print("  ", value)
    }
    fmt.Println()
    var arr1 = [...]int{7, 8, 9, 4, 5, 6}
    for _, v := range arr1 {
        fmt.Print("  ", v)
    }
    fmt.Println()

    var str = [5]string{2: "hello", 4: "jacob"}
    for i := 0; i < len(str); i++ {
        fmt.Print(" ", str[i])
    }
    fmt.Println("\n", str[0] == "")

注:1.数组是值类型,赋值和传参会复制整个数组,而不是指针,因此改变副本的值不会改变原数组的值

2.值拷贝行为会造成性能问题,通常会建议使用 slice,或数组指针。

3.指针数组 [n]*T,数组指针 *[n]T。

切片

从数组或切片生成新的切片:修改切片会更改原数组

    var arr3 = [5]int{1, 2, 3, 4, 5}
    fmt.Println("arr3:", arr3)
    arr4 := arr3[1:3]
    fmt.Println("arr4", arr4)

    arr4 = append(arr4, 12)
    fmt.Println("arr4", arr4)
    fmt.Println("arr3:", arr3)

arr3: [1 2 3 4 5]                    
arr4 [2 3]                           
arr4 [2 3 12]                        
arr3: [1 2 3 12 5]    

直接声明新的切片

// 声明字符串切片
var strList []string

使用make()函数构造切片

make( []Type, size, cap )

a := make([]int, 2)
b := make([]int, 2, 10)
fmt.Println(a, b)
fmt.Println(len(a), len(b))

[0 0] [0 0]
2 2

注意:Go 中函数传参仅有值传递一种方式;

func main() {
    arr := [5]int{1, 3, 5, 6, 7}
    fmt.Printf("addr:%p\n", &arr)// addr:0xc42001a1e0
    s1 := arr[:]
    fmt.Printf("addr:%p\n", &s1)// addr:0xc42000a060

    changeSlice(s1)
}

func changeSlice(s []int) {
    fmt.Printf("addr:%p\n", &s)// addr:0xc42000a080
    fmt.Printf("addr:%p\n", &s[0])// addr:0xc42001a1e0
}

代码中定义了一个数组 arr,然后用它生成了一个slice。如果go中存在引用传递,形参 s 的地址应该与实参 s1 一样(上面c++的证明),通过实际的情况我们发现它们具备完全不同的地址,也就是传参依然发生了拷贝——值传递。

但是这里有个奇怪的现象,大家看到了 arr 的地址与 s[0] 有相同的地址,这也就是为什么我们在函数内部能够修改 slice 的原因,因为当它作为参数传入函数时,虽然 slice 本身是值拷贝,但是它内部引用了对应数组的结构,因此 s[0] 就是 arr[0] 的引用,这也就是能够进行修改的原因。

map的基本使用

make(map[KeyType]ValueType, [cap])
    scoreMap := make(map[string]int, 8)
    scoreMap["张三"] = 90
    scoreMap["小明"] = 100
    fmt.Println(scoreMap)
    fmt.Println(scoreMap["小明"])
    fmt.Printf("type of a:%T\n", scoreMap)

    fmt.Println()
    
    userInfo := map[string]string{
        "username": "pprof.cn",
        "password": "123456",
    }
    fmt.Println(userInfo)

map[小明:100 张三:90]
100                                   
type of a:map[string]int              
                                      
map[password:123456 username:pprof.cn]

判断key是否存在

    v, ok := scoreMap["张三"]
    if ok {
        fmt.Println(v)
    } else {
        fmt.Println("查无此人")
    }

Go语言中使用for range遍历map。

    scoreMap := make(map[string]int)
    scoreMap["张三"] = 90
    scoreMap["小明"] = 100
    scoreMap["王五"] = 60
    for k, v := range scoreMap {
        fmt.Println(k, v)
    }

使用delete()函数删除键值对

 delete(map, key)

结构体

type person struct {
    name string
    city string
    age  int8
}

func main() {
    var p1 person
    p1.name = "pprof.cn"
    p1.city = "北京"
    p1.age = 18
    fmt.Printf("p1=%v\n", p1)  //p1={pprof.cn 北京 18}
    fmt.Printf("p1=%#v\n", p1) //p1=main.person{name:"pprof.cn", city:"北京", age:18}
}

匿名结构体:定义一些临时数据结构等场景下还可以使用匿名结构体。

func main() {
    var user struct{Name string; Age int}
    user.Name = "pprof.cn"
    user.Age = 18
    fmt.Printf("%#v\n", user)
}

创建指针类型结构体

var p2 = new(person)
p2.name = "测试"
p2.age = 18
p2.city = "北京"
fmt.Printf("p2=%#v\n", p2) //p2=&main.person{name:"测试", city:"北京", age:18}

取结构体的地址实例化

使用&对结构体进行取地址操作相当于对该结构体类型进行了一次new实例化操作。

p3 := &person{}
fmt.Printf("%T\n", p3)     //*main.person
fmt.Printf("p3=%#v\n", p3) //p3=&main.person{name:"", city:"", age:0}
p3.name = "博客"
p3.age = 30
p3.city = "成都"
fmt.Printf("p3=%#v\n", p3) //p3=&main.person{name:"博客", city:"成都", age:30}

结构体初始化

type person struct {
    name string
    city string
    age  int8
}
func main() {
    var p4 person
    fmt.Printf("p4=%#v\n", p4) //p4=main.person{name:"", city:"", age:0}
}

使用键值对初始化

p5 := person{
    name: "pprof.cn",
    city: "北京",
    age:  18,
}
fmt.Printf("p5=%#v\n", p5) //p5=main.person{name:"pprof.cn", city:"北京", age:18}

p6 := &person{
    name: "pprof.cn",
    city: "北京",
    age:  18,
}
fmt.Printf("p6=%#v\n", p6) //p6=&main.person{name:"pprof.cn", city:"北京", age:18}

使用值的列表初始化

p8 := &person{
    "pprof.cn",
    "北京",
    18,
}
fmt.Printf("p8=%#v\n", p8) //p8=&main.person{name:"pprof.cn", city:"北京", age:18}

    1.必须初始化结构体的所有字段。
    2.初始值的填充顺序必须与字段在结构体中的声明顺序一致。
    3.该方式不能和键值初始化方式混用。

结构体定义并初始化

    d := struct {
        fn func() string
    }{
        fn: func() string { return "Hello, World!" },
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值