Golang中指针指示器的设计是否令人困惑?

Golang中指针指示器的设计是否令人困惑? 大家好,

我正在学习指针,注意到在定义指针时我们使用 &a(假设 a 是一个变量),但在函数中使用指针时(无论是作为接收器还是返回类型)却使用 *a。所以,对于刚接触 Go 语言的我来说,感觉这有点令人困惑。你们怎么看?

谢谢

7 回复

明白了,谢谢!

更多关于Golang中指针指示器的设计是否令人困惑?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


“&” 操作符返回变量的地址,通常将其赋值给指针类型的变量。 “*” 将变量定义为指针(例如 *int 可以理解为指向整型的指针)

两者都是指针。 因此执行 p:= &a 等同于你可以写成 var p *int = &a

&a 是将变量的地址赋给指针,而不是创建指针。

例如

package main

import (
	"fmt"
)

func main() {
	a := 1
	p := &a

	var q *int = &a

	fmt.Printf("a=%d, p=%v, q=%v", a, p, q)
}

Yamil_Bracho:

package main import ( "fmt" ) func main() { a := 1 p := &a var q *int = &a fmt.Printf("a=%d, p=%v, q=%v", a, p, q) }

以下是我得到的结果:

a=1, p=0xc000016098, q=0xc000016098

所以p和q是相同的。你认为p不是指针而q是指针吗?

感谢您的快速回复,但这正是我感到困惑的地方。假设 a := 1,然后定义一个指针 p := &a,请注意指针只是一个变量 p,没有任何前缀(没有 *)。当我们进行解引用时,使用 *p 来获取 a 的值。

如果这是正确的,那么在指针前添加前缀 * 就是解引用,它会调用存储在 p 内存地址中的变量值。

所以我的问题仍然是:当我们使用 func (ob *somevariable) () {} 时,使用 * 表示指针不会让人感到困惑吗?

func (ob *somevariable) () {}

在Go语言中,指针的设计遵循C语言的传统,但语法更简洁,理解其逻辑后并不复杂。让我通过示例解释&*的用法。

1. & 操作符用于获取变量的内存地址(即生成指针):

a := 42
ptr := &a  // ptr 现在是一个指向a的指针,类型为 *int

这里,&a 返回变量 a 的内存地址,赋值给指针变量 ptr

2. * 操作符用于解引用指针(即访问指针指向的值):

fmt.Println(*ptr)  // 输出: 42,通过 *ptr 获取 ptr 指向的值
*ptr = 100         // 通过指针修改 a 的值
fmt.Println(a)     // 输出: 100

在函数中使用指针时,* 用于声明指针类型或操作指针指向的数据。

3. 函数中的指针示例:

  • 作为参数:
func modifyValue(ptr *int) {
    *ptr = 200  // 解引用指针并修改值
}

func main() {
    x := 10
    modifyValue(&x)  // 传递 x 的地址
    fmt.Println(x)   // 输出: 200
}
  • 作为返回类型:
func createPointer() *int {
    v := 5
    return &v  // 返回局部变量 v 的指针(Go 逃逸分析处理内存安全)
}

func main() {
    p := createPointer()
    fmt.Println(*p)  // 输出: 5
}
  • 作为接收器(在方法中):
type MyStruct struct {
    value int
}

func (m *MyStruct) setValue(v int) {
    m.value = v  // 自动解引用:等价于 (*m).value = v
}

func main() {
    obj := MyStruct{value: 1}
    obj.setValue(10)        // 编译器自动处理为 (&obj).setValue(10)
    fmt.Println(obj.value)  // 输出: 10
}

在方法接收器中,Go 自动处理指针解引用,无需显式使用 * 访问字段。

总结:

  • & 用于取地址生成指针。
  • * 用于声明指针类型或解引用指针。
  • 初始时可能混淆,但通过实践(如修改函数外变量或避免大结构体复制)会熟悉。Go 的指针设计减少了内存复制并支持共享数据,是高效编程的关键。
回到顶部