English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
En el lenguaje de programación Go, un puntero es una variable que se utiliza para almacenar la dirección de memoria de otra variable. Los punteros en Golang también se conocen como variables especiales.VariableSe utiliza para almacenar algunos datos en una dirección de memoria específica del sistema. Siempre se encuentra la dirección de memoria en formato hexadecimal (con 0x al principio, como 0xFFAAF, etc.).
¿Para qué sirve un puntero?
Para entender este puntero, primero, debemos entender el concepto de variable. Una variable es el nombre asignado a una ubicación de almacenamiento de datos real. Para acceder a los datos almacenados, necesitamos la dirección de esa ubicación de almacenamiento específica. Recordar manualmente todas las direcciones de memoria (en formato hexadecimal) es una carga, por eso usamos variables para almacenar datos y solo podemos acceder a las variables a través de sus nombres.
Golang también permite usar expresiones literales para almacenar números hexadecimales en variables, es decir, desde0xEl número inicial es un número hexadecimal.
Ejemplo:En el siguiente programa, almacenaremos el número hexadecimal en una variable. Pero como puede ver, el tipo del valor esintY se puede guardar como decimal, o decirintEl valor decimal del tipo está siendo almacenado. Sin embargo, el punto principal de este ejemplo es que estamos almacenando un valor hexadecimal (considerado como una dirección de memoria), pero no es un puntero porque no apunta a otra posición de memoria de cualquier otra variable. Es solo una variable definida por el usuario. Por lo tanto, se necesita usar un puntero.
//Almacenar valor hexadecimal package main import "fmt" func main() { //Almacenar en hexadecimal //Valor en la variable x := 0xFF y := 0x9C // Mostrar valor fmt.Printf("El tipo de variable de x es %T\n", x) fmt.Printf("El valor hexadecimal de x es %X\n", x) fmt.Printf("El valor decimal de x es %v\n", x) fmt.Printf("El tipo de variable de y es %T\n", y) fmt.Printf("El valor hexadecimal de y es %X\n", y) fmt.Printf("El valor decimal de y es %v\n", y) }
Salida:
El tipo de variable x es int El valor hexadecimal de x es FF El valor decimal de x es 255 El tipo de variable y es int El valor hexadecimal de y es 9C El valor decimal de y es 156
Un puntero es un tipo especial de variable que no solo se utiliza para almacenar la dirección de memoria de otras variables, sino que también apunta a una posición en la memoria y proporciona un método para buscar el valor almacenado en esa posición en la memoria. Generalmente se conoce como tipo especial de variable porque prácticamente se declara como variable, pero con*(operador de desreferencia).
Antes de comenzar, utilizaremos dos operadores importantes en los punteros, a saber
*Operador También se conoce como operador de desreferencia, utilizado para declarar variables de puntero y acceder al valor almacenado en la dirección.
&operador Se conoce como operador de dirección, utilizado para devolver la dirección de la variable o acceder al puntero de la dirección de la variable.
Declarar un puntero:
var pointer_name *Data_Type
Ejemplo:A continuación, se muestra un puntero de tipo cadena, que solo puede almacenarCadenaLa dirección de memoria de la variable.
var s *string
Inicialización de puntero:Para esto, necesita usar el operador de dirección para inicializar el puntero con la dirección de memoria de otra variable, como se muestra en el siguiente ejemplo:
//Declaración de variable normal var a = 45 //Usar el puntero inicializado s //La dirección de memoria de la variable a var s *int = &a
// Un programa de Go para demostrar la declaración //Y la inicialización de puntero package main import "fmt" func main() { //Definir una variable normal var x int = 5748 //Declaración de puntero var p *int //Inicialización de puntero p = &x //Mostrar resultados fmt.Println("El valor almacenado en x = ", x) fmt.Println("La dirección de memoria de x = ", &x) fmt.Println("El valor almacenado en la variable p = ", p) }
Salida:
El valor almacenado en x = 5748 La dirección de memoria de x = 0xc000066090 El valor almacenado en la variable p = 0xc000066090
Puntos importantes:
El valor por defecto o cero del puntero siempre es nil. O también se puede decir que el puntero no inicializado siempre tendrá el valor nil.
//El valor nil de puntero package main import "fmt" func main() { //Definir puntero var s *int // Mostrar resultados fmt.Println("s = ", s) }
Salida:
s = <nil>
La declaración y la inicialización de punteros se pueden realizar en una sola línea.
var s *int = &a
Si se desea especificar tanto el tipo de datos como la declaración de puntero, el puntero podrá manejar la dirección de memoria del tipo de datos especificado. Por ejemplo, si se utiliza un puntero de tipo cadena, la dirección de la variable proporcionada al puntero será solo la variable de tipo cadena, y no otro tipo.
Para superar estos problemas, se puede utilizarla palabra clave varel concepto de inferencia de tipo. No es necesario especificar el tipo de datos durante la declaración. El tipo de un puntero también puede ser determinado por el compilador como una variable común. Aquí, no utilizaremos*Operador. Cuando usamos la dirección de otra variable para inicializar una variable, se determina internamente por el compilador.
// Demostración de programa en Golang //El operador. Cuando usamos la dirección de otra variable para inicializar una variable, se determina internamente por el compilador. //Variable de puntero package main import "fmt" func main() { //Usando la palabra clave var //No hemos definido //Cualquier tipo de variable con tipo var y = 458 //Usando variable de puntero // Palabra clave var, sin especificar //Tipo var p = &y fmt.Println("El valor almacenado en y = ", y) fmt.Println("La dirección de y = ", &y) fmt.Println("El valor almacenado en la variable de puntero p = ", p) }
Salida:
El valor almacenado en y = 458 La dirección de y = 0xc0000120a8 El valor almacenado en la variable de puntero p = 0xc0000120a8
También puede usarabreviatura(:=)Sintaxis para declarar e inicializar variables de puntero. Si usamos&(dirección)El operador pasa la dirección de la variable a él, y el compilador determina internamente que la variable es un puntero.
// Demostración de programa en Golang //Usando la sintaxis de atajo en //Variable de puntero package main import "fmt" func main() { //Usando el operador := para la declaración //Iniciando la variable y := 458 //Usando una variable de puntero //Asignada a través de := //La dirección de la variable y p := &y fmt.Println("El valor almacenado en y = ", y) fmt.Println("La dirección de y = ", &y) fmt.Println("El valor almacenado en la variable de puntero p = ", p) }
Salida:
El valor almacenado en y = 458 La dirección de y = 0xc000066090 El valor almacenado en la variable de puntero p = 0xc000066090
Es conocido que*El operador también se llama operador de desreferencia. No solo se utiliza para declarar variables de puntero, sino también para acceder al valor almacenado en la variable a la que apunta el puntero, generalmente se llamaIndirecto o desreferencia。*El operador también se llama valor en la dirección。Vamos a dar un ejemplo para entender mejor este concepto:
// Ejemplo de programa en Golang //Concepto de desreferencia de puntero package main import "fmt" func main() { //Usando la palabra clave var //No hemos definido //Cualquier tipo de variable con tipo var y = 458 //Usando variable de puntero // Palabra clave var, sin especificar //Tipo var p = &y fmt.Println("El valor almacenado en y = ", y) fmt.Println("La dirección de y = ", &y) fmt.Println("El valor almacenado en la variable de puntero p = ", p) //Esto es desreferenciar el puntero //Usado antes del puntero*Operador //Variable para acceder al valor almacenado //Puntero que apunta a la variable fmt.Println("El valor almacenado en y(",*p) = ", *p) }
Salida:
El valor almacenado en y = 458 La dirección de y = 0xc0000120a8 El valor almacenado en la variable de puntero p = 0xc0000120a8 El valor almacenado en y(*p) = 458
También puede cambiar el valor del puntero o la ubicación en memoria, en lugar de asignar un nuevo valor a la variable.
package main import "fmt" func main() { //Usando la palabra clave var //No hemos definido //Sin especificar el tipo de variable var y = 458 //Usando variable de puntero // Palabra clave var, sin especificar tipo var p = &y fmt.Println("El valor almacenado antes de cambiar en y = ", y) fmt.Println("La dirección de y = ", &y) fmt.Println("El valor almacenado en la variable de puntero p = ", p) //Esto es desreferenciar el puntero //Usado antes del puntero*Operador //Variable para acceder al valor almacenado //Puntero que apunta a la variable fmt.Println("El valor almacenado antes de cambiar en y(*El valor en p) = ", *p) //Cambiando el valor de y mediante asignación //El nuevo valor del puntero *p = 500 fmt.Println("El valor almacenado después de cambiar en y(*El valor en p) = ", y) }
Salida:
El valor almacenado antes de cambiar en y = 458 La dirección de y = 0xc0000120a8 El valor almacenado en la variable de puntero p = 0xc0000120a8 El valor almacenado antes de cambiar en y(*p) valor de 458 El valor almacenado después de cambiar en y(*p) valor de 500