Golang 指针

默认指针类型

类型 名称 长度 默认值
pointer 指针 nil
array 数组 0
slice 切片 nil
map 字典 nil
struct 结构体

1. 变量和内存地址

  • go 语言中指针是很容易学习的,比 C 中容易的多,它可以更简单地执行一些任务
  • 每个变量都有内存地址,可以理解为变量来操作对应的内存
  • go 语言的取地址符是&,放到一个变量前使用就会返回相应变量的内存地址
package main

import "fmt"

func main() {
    var a int
    a = 0
    // 使用 & 符号获取变量地址
    fmt.Println(&a)
    fmt.Printf("变量a的地址是: %x\n", &a)
}

2. 值类型和指针类型

  • 普通变量存储的是对应类型的值,这些类型叫值类型(var a int = 10)
  • 指针也是一个变量,用于存储另一个变量的内存地址,变量存的是值,指针存的是一个地址,这个地址指向的空间存的才是值,所以指针又叫引用类型
  • 与变量类似,使用前需要声明
  • 声明指针的格式:var 指针变量名 *指针类型
  • 指针的使用
package main

import "fmt"

func main() {
    var a int
    a = 10
    var p *int
    // 指针类型存变量地址
    p = &a

    fmt.Printf("变量a的地址: %x\n", &a)
    fmt.Printf("指针类型p指向a地址的值: %x\n", p)
    fmt.Printf("指针类型p获取指针变量的值: %d\n", *p)
}

3. 空指针

  • 当一个指针被定义后没有分配到任何变量时,它的值为 nil
  • 空指针的判断
package main

import "fmt"

func main() {
    var p *int
    fmt.Println(p)
    fmt.Printf("p的值%x\n", p)

    // 判断类型是否为空
    if p != nil {
        fmt.Println("非空")
    } else {
        fmt.Println("空")
    }
}

4. 值传递和引用传递

package main

import "fmt"

func swap(a, b *int) {
    // 交换语法,必须交换值
    //a, b = b, a
    *a, *b = *b, *a
}

func main() {
    a, b := 10, 20
    fmt.Println(a, b)
    swap(&a, &b)
    fmt.Println(a, b)
}
package main

import "fmt"

func swap(a, b *int) (*int, *int) {
    a, b = b, a
    return a, b
}

func main() {
    a, b := 10, 20
    fmt.Println(a, b)
    c, d := swap(&a, &b)
    fmt.Println(*c, *d)

    fmt.Println(&a, &b)

    // 这里可以打断点,导致连锁反应
    a = *c
    b = *d

    fmt.Println(a, b)
}

5. new()和 make()

  • make()用来分配引用类型的内存,例如 slice、map、channel,并且初始化内存
  • new()用来分配各种类型的内存,但它不会初始化内存
  • make()的用途不同于 new(),它只能创建 slice、map、channel,并返回类型为 T(非指针)的已初始化(非零值)的值
package main

import "fmt"

func main() {
    a := new([]int)
    fmt.Println(a)

    b := make([]int, 10, 20)
    fmt.Println(b)
}
// 输出结果
// &[]
// [0 0 0 0 0 0 0 0 0 0]

猜你喜欢

转载自www.cnblogs.com/zhichaoma/p/12510011.html