golang语法-----指针

一、核心语法

1、取地址符 &,用在一个变量前面,获取这个变量的内存地址。

package main

import "fmt"

func main() {
    name := "Alice" // 变量 name,它的值是 "Alice"

    // &name 获取变量 name 的内存地址
    // p 是一个指针变量,它存储了 name 的地址
    // p 的类型是 *string,读作 "string 类型的指针"
    p := &name 
    
    fmt.Println("变量 name 的值:", name)
    fmt.Println("变量 name 的内存地址:", p) // 会打印一个像 0x... 的十六进制地址
}

2、解引用符 *,用在一个指针变量前面,获取该指针指向的地址上存储的那个值。

    // ... p 是指向 name 的指针
    
    // *p 表示“访问 p 指针指向的那个变量的值”
    fmt.Println("通过指针 p 访问到的值:", *p) // 输出: Alice

    // 通过指针修改原变量的值
    *p = "Bob" // 这等价于 name = "Bob"
    
    fmt.Println("修改后,原变量 name 的值:", name) // 输出: Bob
    fmt.Println("修改后,通过指针 p 访问到的值:", *p) // 输出: Bob

3、空指针,当一个指针被定义后没有分配到任何变量时,它的值为 nil

package main

import "fmt"

func main() {
    var p *string
    fmt.Println(p)
    fmt.Printf("p的值是%s/n", p)
    if p != nil {
        fmt.Println("非空")
    } else {
        fmt.Println("空值")
    }
}

4、安全特性

(1)无指针运算:不允许像在 C 语言里那样对指针进行加减运算(例如 p++),杜绝了一大类内存访问错误。

你只能从一个指针移动到另一个指针(通过 unsafe 包,但新手绝对不要碰)。

(2)无法获取任意地址的指针: 不能将一个整数强制转换成指针,无法指向任意内存地址。

二、指针的应用

1、在函数间共享和修改数据

Go 语言的函数参数传递都是值传递,意味着把一个变量传给函数时,函数得到的是这个变量的一个副本,比如:

func changeValue(num int) {
    num = 100 // 这里修改的是 num 的副本,不会影响外面的 a
}

func main() {
    a := 10
    changeValue(a)
    fmt.Println("a 的值是:", a) // 输出: a 的值是: 10
}

通过传递变量的地址(指针),函数就可以通过地址直接操作原始变量,而不是它的副本

// 函数接收一个 *int 类型的参数,即一个指向 int 的指针
func changeValueByPointer(ptr *int) {
    *ptr = 100 // 通过指针,直接修改了指针指向地址上的值
}

func main() {
    a := 10
    changeValueByPointer(&a) // 把 a 的内存地址传给函数
    fmt.Println("a 的值是:", a) // 输出: a 的值是: 100
}

2、指向结构体的指针

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{Name: "David", Age: 40}
    
    // a. 创建一个指向结构体的指针
    ptr := &p
    
    // b. 访问结构体字段
    // 标准写法是 (*ptr).Name,需要解引用再访问字段
    fmt.Println("姓名:", (*ptr).Name)
    
    // c. 语法糖 (Syntactic Sugar)
    // Go 语言为了方便,允许你直接用 ptr.Name 来代替 (*ptr).Name
    // 编译器会自动帮你转换。这种写法更常用!
    fmt.Println("姓名 (语法糖):", ptr.Name) 
    
    // 通过指针修改字段
    ptr.Age = 41
    fmt.Println("修改后的年龄:", p.Age) // 输出: 41
}

3、new 函数:创建指针

除了用 & 获取已有变量的地址,你还可以用内置的 new 函数来创建一个指向某个类型零值的指针。

new(T) 的作用是:

  1. 分配一块内存来存储 T 类型的零值。
  2. 返回这块内存的地址,即一个 *T 类型的指针。
// 创建一个指向 int 零值 (0) 的指针
var p1 = new(int) 
fmt.Println("p1 指向的值:", *p1) // 输出: 0
*p1 = 123
fmt.Println("修改后 p1 指向的值:", *p1) // 输出: 123

// 创建一个指向 Person 零值的指针
var p2 = new(Person)
p2.Name = "Eve"
fmt.Println("p2 指向的人:", *p2) // 输出: {Eve 0}

你可能感兴趣的:(编程语言笔记,golang,开发语言)