English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Um ponteiro em linguagem de programação Go é uma variável usada para armazenar o endereço de memória de outra variável. Os ponteiros no Golang também são chamados de variáveis especiais.VariávelUsado para armazenar alguns dados em um endereço específico de memória do sistema. Sempre encontrar endereços de memória em formato hexadecimal (começando com 0x, como 0xFFAAF, etc.).
A função do ponteiro?
Para entender esse ponteiro, primeiro, devemos entender o conceito de variável. Uma variável é o nome atribuído a um local de armazenamento de dados real. Para acessar os dados armazenados, precisamos do endereço específico daquele local de armazenamento. Lembrar manualmente de todos os endereços de memória (em formato hexadecimal) é uma despesa, e é por isso que usamos variáveis para armazenar dados e podemos acessar as variáveis apenas usando o nome delas.
O Golang permite usar expressões literais para armazenar números hexadecimais em variáveis, ou seja, a partir de0xOs números iniciais são números hexadecimais.
Exemplo:No programa a seguir, armazenaremos números hexadecimais em variáveis. No entanto, você pode ver que o tipo do valor éinte salvar como decimal, ou sejaintO valor decimal do tipo está sendo armazenado. No entanto, o ponto principal deste exemplo é que estamos armazenando valores hexadecimais (considerados endereços de memória), mas não são ponteiros, pois não apontam para nenhuma outra posição de memória de nenhuma outra variável. É apenas uma variável definida pelo usuário. Portanto, precisamos usar ponteiros.
//Armazenamento do valor hexadecimal package main import "fmt" func main() { //Armazenamento hexadecimal //O valor dentro da variável x := 0xFF y := 0x9C // Mostrar valor fmt.Printf("O tipo da variável x é %T\n", x) fmt.Printf("O valor hexadecimal de x é %X\n", x) fmt.Printf("O valor decimal de x é %v\n", x) fmt.Printf("O tipo da variável y é %T\n", y) fmt.Printf("O valor hexadecimal de y é %X\n", y) fmt.Printf("O valor decimal de y é %v\n", y) }
Saída:
O tipo da variável x é int O valor hexadecimal de x é FF O valor decimal de x é 255 O tipo da variável y é int O valor hexadecimal de y é 9C O valor decimal de y é 156
Um ponteiro é um tipo especial de variável que não só é usado para armazenar o endereço de memória de outras variáveis, mas também aponta para a posição da memória e fornece um método para encontrar o valor armazenado na posição da memória. Ele é geralmente chamado de tipo especial de variável porque quase é declarado como uma variável, mas com*(operador de desreferência).
Antes de começar, vamos usar dois operadores importantes no ponteiro, ou seja
*Operador Também conhecido como operador de desreferência, usado para declarar variáveis de ponteiros e acessar os valores armazenados nos endereços.
Operador & Conhecido como operador de endereço, usado para retornar o endereço da variável ou para acessar o ponteiro do endereço da variável.
Declarar um ponteiro:
var pointer_name *Data_Type
Exemplo:Aqui está um ponteiro de tipo string, que pode armazenar apenasCadeia de caracteresO endereço de memória da variável.
var s *string
Inicialização de ponteiro:Para isso, você precisa usar o operador de endereço para inicializar o ponteiro com o endereço de memória de outra variável, como mostrado no exemplo a seguir:
//Declaração de variável normal var a = 45 //Usar ponteiro inicializado s //O endereço de memória da variável a var s *int = &a
// Um programa Go para demonstrar a declaração //e inicialização de ponteiro package main import "fmt" func main() { //Definir uma variável normal var x int = 5748 //Declaração de ponteiro var p *int //Inicializar ponteiro p = &x //Mostrar resultado fmt.Println("O valor armazenado no x = ", x) fmt.Println("O endereço de memória do x = ", &x) fmt.Println("O valor armazenado na variável p = ", p) }
Saída:
O valor armazenado no x = 5748 O endereço de memória do x = 0xc000066090 O valor armazenado na variável p = 0xc000066090
Ponto importante:
O valor padrão ou zero de ponteiro sempre é nil. Ou você pode dizer que o ponteiro não inicializado sempre terá o valor nil.
//O valor nil de ponteiro package main import "fmt" func main() { //Definir ponteiro var s *int // Mostrar resultado fmt.Println("s = ", s) }
Saída:
s = <nil>
A declaração e inicialização de ponteiros podem ser realizadas em uma linha.
var s *int = &a
Se for necessário especificar tanto o tipo de dados quanto a declaração de ponteiros, o ponteiro será capaz de manipular o endereço de memória do tipo de dados especificado. Por exemplo, se você usar um ponteiro de tipo string, o endereço fornecido ao ponteiro será apenas o tipo de dados variável de string, e não outro tipo qualquer.
Para superar esses problemas, pode-se usara palavra-chave varO conceito de inferência de tipo. Não é necessário especificar o tipo de dados durante a declaração. O tipo de um ponteiro de variável também pode ser determinado pelo compilador como uma variável normal. Aqui, não utilizaremos*O operador. Quando usamos o endereço de outra variável para inicializar uma variável, ele é determinado internamente pelo compilador.
// Programa em Golang para demonstração //para inferência de tipo //Variável ponteiro package main import "fmt" func main() { //Usando a palavra-chave var //Nós não definimos //Qualquer tipo de variável com tipo var y = 458 //Usando ponteiro variável // Palavra-chave var, sem especificar //Tipo var p = &y fmt.Println("O valor armazenado em y = ", y) fmt.Println("O endereço de y = ", &y) fmt.Println("O valor armazenado no ponteiro variável p = ", p) }
Saída:
O valor armazenado em y = 458 O endereço de y = 0xc0000120a8 O valor armazenado no ponteiro variável p = 0xc0000120a8
Você também pode usarabreviação(:=)Sintaxe para declarar e inicializar variáveis de ponteiro. Se usarmos&(endereço)O operador passa o endereço da variável para ele, então o compilador determina internamente que a variável é um ponteiro.
// Programa em Golang para demonstração //Usando a sintaxe abreviada //Variável ponteiro package main import "fmt" func main() { //Usando o operador := para declaração //E inicializar a variável y := 458 //Usando um ponteiro variável //Atribuído por meio de := //Endereço da variável y p := &y fmt.Println("O valor armazenado em y = ", y) fmt.Println("O endereço de y = ", &y) fmt.Println("O valor armazenado no ponteiro variável p = ", p) }
Saída:
O valor armazenado em y = 458 O endereço de y = 0xc000066090 O valor armazenado no ponteiro variável p = 0xc000066090
Conhecido como*O operador também é chamado de operador de desreferenciamento. Ele não só é usado para declarar variáveis de ponteiro, mas também para acessar o valor armazenado na variável apontada pelo ponteiro, geralmente chamado deIndireto ou desreferenciamento。*O operador também é chamado de valor no endereço。Vamos dar um exemplo para entender melhor esse conceito:
// Exemplo de programa em Golang //Conceito de desreferenciamento de ponteiro package main import "fmt" func main() { //Usando a palavra-chave var //Nós não definimos //Qualquer tipo de variável com tipo var y = 458 //Usando ponteiro variável // Palavra-chave var, sem especificar //Tipo var p = &y fmt.Println("O valor armazenado em y = ", y) fmt.Println("O endereço de y = ", &y) fmt.Println("O valor armazenado no ponteiro variável p = ", p) //Isso é desreferenciar o ponteiro //Usado antes do ponteiro*Operador //Variável para acessar o valor armazenado //Ponteiro que aponta para a variável fmt.Println("O valor armazenado em y = ",*p) = *p) }
Saída:
O valor armazenado em y = 458 O endereço de y = 0xc0000120a8 O valor armazenado no ponteiro variável p = 0xc0000120a8 O valor armazenado em y =*p) = 458
Você também pode alterar o valor do ponteiro ou a posição na memória, em vez de alocar um novo valor para a variável.
package main import "fmt" func main() { //Usando a palavra-chave var //Nós não definimos //Sem especificar o tipo da variável var y = 458 //Usando ponteiro variável // Palavra-chave var, sem especificar tipo var p = &y fmt.Println("O valor armazenado antes da alteração em y = ", y) fmt.Println("O endereço de y = ", &y) fmt.Println("O valor armazenado no ponteiro variável p = ", p) //Isso é desreferenciar o ponteiro //Usado antes do ponteiro*Operador //Variável para acessar o valor armazenado //Ponteiro que aponta para a variável fmt.Println("O valor armazenado antes da alteração em y(*O valor no p) = ", *p) //Alterando o valor de y por meio de atribuição //Novo valor do ponteiro *p = 500 fmt.Println("O valor armazenado após a alteração em y(*O valor no p) = ", y) }
Saída:
O valor armazenado antes da alteração em y = 458 O endereço de y = 0xc0000120a8 O valor armazenado no ponteiro variável p = 0xc0000120a8 O valor armazenado antes da alteração em y(*o valor dentro de p)= 458 O valor armazenado após a alteração em y(*o valor dentro de p)= 500