Почему невозможно добавить целое число в переменную-указатель с разыменовкой в ​​Go? - PullRequest
0 голосов
/ 08 сентября 2018

Исходя из 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. Однако почему можно увеличить значение a на *b++ в первом примере?

Ответы [ 4 ]

0 голосов
/ 08 сентября 2018

Вы добавляете *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

0 голосов
/ 08 сентября 2018

С начала:

b := &a

Здесь b имеет тип *int, указатель на место в памяти, где хранится значение a. Когда вы делаете *b, вы получаете доступ к значению из указателя местоположения b на.

Когда вы делаете *b++, это означает *b = *b + 1, и вы увеличиваете значение в местоположении, на которое указывает указатель b.

b = *b + 1 недопустим, потому что вы пытаетесь добавить *b и 1, оба типа int, к b, который является указателем (тип *int).

0 голосов
/ 08 сентября 2018

Добавление целого числа в переменную с указателем разыменования (целое число) возможно и работает в вашем случае корректно. Однако присвоение этого значения переменной-указателю недопустимо в Go по соображениям безопасности типов. И это обычно не нужно (но есть способ ссылаться на любой данный адрес, хотя). Надеюсь, это проясняет это.

0 голосов
/ 08 сентября 2018

Почему невозможно добавить целое число в переменную-указатель с разыменовкой в ​​Go?

b является указателем и разыменованным b записывается как *b. b = *b + 1 недопустимо, потому что вы пытаетесь преобразовать целое число в указатель, что невозможно даже при явной типизированной вставке. Вместо этого вам нужно изменить данные, на которые указывает указатель, а не сам указатель: *b = *b + 1.

Взгляните на спецификацию Go здесь о том, почему *b++ работает: https://golang.org/ref/spec

Приоритет оператора

Унарные операторы имеют наивысший приоритет. Поскольку операторы ++ и - формируют операторы, а не выражения, они выходят за пределы иерархии операторов. Как следствие, утверждение * p ++ совпадает с (* p) ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...