Viniendo de Python, actualmente estoy aprendiendo Go y tratando de entender los punteros.

He escrito este código para entender el concepto:

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)

Traté de jugar con este código para mejorar mi comprensión. Lo siguiente, sin embargo, no funciona:

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)

Aparentemente, *b es del tipo *int, mientras que el valor 1 es (obviamente) del tipo int. Sin embargo, ¿por qué es posible incrementar el valor de a con *b++ en el primer ejemplo?

2
mamr 8 sep. 2018 a las 10:07

4 respuestas

La mejor respuesta

Desde el principio:

b := &a

Aquí, b es del tipo *int, un puntero a una ubicación en la memoria donde se almacena el valor de a. Cuando haces *b, estás accediendo a un valor desde la ubicación a la que apunta b puntero.

Cuando haces *b++, significa *b = *b + 1 y estás incrementando un valor en la ubicación a la que apunta b puntero.

b = *b + 1 no es válido porque está intentando agregar *b y 1, que son ambos tipos de int, a b, que es un puntero (tipo de *int).

1
eminlala 8 sep. 2018 a las 08:36

¿Por qué no es posible agregar un entero a una variable de puntero "desreferenciado" en Go?

b es un puntero y la b desreferenciada se escribe como *b. b = *b + 1 no es válido porque está intentando convertir un número entero en un puntero, lo que no es posible incluso cuando se escribe de forma explícita. En su lugar, deberá modificar los datos a los que apunta el puntero, no el puntero en sí: *b = *b + 1.

Eche un vistazo a las especificaciones de Go aquí sobre por qué funciona *b++: https://golang.org/ref / spec

Prioridad de la operadora

Los operadores unarios tienen la mayor prioridad. A medida que los operadores ++ y - forman declaraciones, no expresiones, quedan fuera de la jerarquía del operador. Como consecuencia, la declaración * p ++ es la misma que (* p) ++.

1
svsd 8 sep. 2018 a las 08:30

Está agregando un *int a un int. De ahí el error. Como b es un puntero a un entero, para hacer algo con ese entero (lectura o escritura), debe desreferenciarlo. El siguiente código funcionará como se espera. Eso es lo que *b++ hace internamente.

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
}

Pruébalo aquí: https://play.golang.org/p/2RX1CWD-AQC

1
Tushar 8 sep. 2018 a las 11:30

Agregar un entero a una variable de puntero desreferenciado (entero) es posible y funciona correctamente en su caso. Sin embargo, asignar este valor a una variable de puntero no es aceptable en Go por razones de seguridad de tipo. Y normalmente no es necesario (aunque hay una forma de hacer referencia a cualquier dirección dada). Espero que esto lo aclare.

0
Ravi 8 sep. 2018 a las 10:21