【问题标题】:Why is it not possible to add an integer to a "dereferenced" pointer variable in Go?为什么不能将整数添加到 Go 中的“取消引用”指针变量?
【发布时间】:2019-02-13 10:02:06
【问题描述】:

我来自 Python,目前正在学习 Go 并试图用指针来解决问题。

为了理解这个概念,我编写了这段代码:

a := 1
b := &a
fmt.Println(b) // Shows the memory address of a
fmt.Println(*b) // Shows the value 1
*b++
fmt.Println(a) // Shows the value 2 (as expected)

我尝试使用这段代码来提高我的理解力。但是,以下方法不起作用:

a := 1
b := &a
fmt.Println(b) // Shows the memory address of a
fmt.Println(*b) // Shows the value 1
b = *b + 1 // Compile error: invalid operation: b * +1 (mismatched types *int and int)
fmt.Println(a)

显然,*b*int 类型,而值 1 是(显然)int 类型。但是,为什么可以在第一个示例中使用 *b++ 增加 a 的值?

【问题讨论】:

  • *b++ 代表*b = *b + 1,而不是b = *b + 1
  • b 的类型为 *int*b 的类型为 int*b + 1 很好(并产生 int)。问题是分配给b,它是*int,而不是int。写b = *bb = 1 会得到同样的错误。
  • 您使用的是什么 Go 版本?我没有收到您发布的错误;我得到“不能使用 *b + 1 (type int) as type *int in assignment”;这更清楚,在这种情况下可能会避免你的困惑。

标签: pointers go types


【解决方案1】:

为什么在 Go 中不能将整数添加到“取消引用”的指针变量?

b 是一个指针,取消引用的b 写为*bb = *b + 1 无效,因为您正在尝试将整数转换为指针,即使显式类型转换也是不可能的。您需要修改指针指向的数据,而不是指针本身:*b = *b + 1

在此处查看 Go 规范,了解 *b++ 为何有效:https://golang.org/ref/spec

运算符优先级

一元运算符具有最高优先级。由于 ++ 和 -- 运算符构成语句而不是表达式,因此它们位于运算符层次结构之外。因此,语句 *p++ 与 (*p)++ 相同。

【讨论】:

    【解决方案2】:

    从头开始:

    b := &a

    这里,b*int 类型,它是指向内存中存储 a 值的位置的指针。当您执行*b 时,您正在从b 指针指向的位置访问一个值。

    当您执行*b++ 时,它代表*b = *b + 1,并且您正在增加b 指针指向的位置的值。

    b = *b + 1 无效,因为您试图将*b1(两者都是int 的类型)添加到b,它是一个指针(*int 的类型)。

    【讨论】:

      【解决方案3】:

      将整数添加到取消引用(整数)指针变量是可能的,并且在您的情况下可以正常工作。但是,出于类型安全的原因,在 Go 中将这个值分配给指针变量是不可接受的。而且通常不需要它(但有一种方法可以引用任何给定的地址)。希望这可以澄清它。

      【讨论】:

        【解决方案4】:

        您正在将*int 添加到int。因此,错误。 由于 b 是指向整数的指针,因此要对该整数执行任何操作(读取或写入),您需要取消引用它。下面的代码将按预期工作。这就是*b++ 在内部所做的。

        package main
        
        import (
            "fmt"
        )
        
        func main() {
            a := 1
            b := &a
            fmt.Println(b)  // Shows the memory address of a
            fmt.Println(*b) // Shows the value 1
            *b = *b + 1     // No Compile error
            fmt.Println(a)  // Shows the value 2
        }
        

        在这里试试: https://play.golang.org/p/2RX1CWD-AQC

        【讨论】:

          猜你喜欢
          • 2018-01-10
          • 2011-01-24
          • 2011-02-24
          • 1970-01-01
          • 1970-01-01
          • 2018-02-03
          • 1970-01-01
          • 1970-01-01
          • 2014-03-03
          相关资源
          最近更新 更多