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

Coming from Python, I'm currently learning Go and trying to wrap my head around pointers.

I've written this code in order to understand the concept:

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)

I tried to play around with this code to improve my understanding. The following, however, does not work:

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)

Apparently, *b is of type *int, while the value 1 is (obviously) of type int. However, why is it possible to increment the value of a with *b++in the first example?

From the beginning:

b := &a

Here, b is of type *int, a pointer to a location in memory where value of a is stored. When you do *b, you are accessing a value from the location b pointer points to.

When you do *b++, it stands for *b = *b + 1 and you are incrementing a value on the location b pointer points to.

b = *b + 1 is invalid because you are trying to add *b and 1, which are both type of int, to b, which is a pointer (type of *int).

Why is it not possible to add an integer to a “dereferenced” pointer variable in Go?

b is a pointer and dereferenced b is written as *b. b = *b + 1 is invalid because you're trying to convert an integer to a pointer, which is not possible even when explicitly typecasted. You'll need to instead modify the data that pointer is pointing to, not the pointer itself: *b = *b + 1.

Take a look at the Go spec here regarding why *b++ works: https://golang.org/ref/spec

Operator precedence

Unary operators have the highest precedence. As the ++ and -- operators form statements, not expressions, they fall outside the operator hierarchy. As a consequence, statement *p++ is the same as (*p)++.

Adding an integer to a dereferenced (integer) pointer variable is possible and is working in your case correctly. However, assigning this value to a pointer variable is not acceptable in Go for type safety reasons. And it is normally not needed (but there is a way to reference any given address though). Hope this clarifies it.

You are adding a *int to an int. Hence, the error. As b is a pointer to an integer, to do anything with that integer(read or write), you need to de-reference it. Below code will work as expected. That's what *b++ does internally.

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
}

Try it here: https://play.golang.org/p/2RX1CWD-AQC