Eu tenho um tipo de estrutura com um *int64
campo.
type SomeType struct {
SomeField *int64
}
Em algum ponto do meu código, quero declarar um literal disso (digamos, quando eu sei que o valor mencionado deve ser 0, ou apontando para 0, você sabe o que quero dizer)
instance := SomeType{
SomeField: &0,
}
... exceto que isso não funciona
./main.go:xx: cannot use &0 (type *int) as type *int64 in field value
Então eu tento isso
instance := SomeType{
SomeField: &int64(0),
}
... mas isso também não funciona
./main.go:xx: cannot take the address of int64(0)
Como eu faço isso? A única solução que posso encontrar é usar uma variável de espaço reservado
var placeholder int64
placeholder = 0
instance := SomeType{
SomeField: &placeholder,
}
Nota: a Edit: não, não. Desculpe por isto.&0
sintaxe funciona bem quando é um * int em vez de um *int64
.
Editar:
Aparentemente, minha pergunta era ambígua demais. Estou procurando uma maneira de afirmar literalmente a *int64
. Isso pode ser usado dentro de um construtor ou para declarar valores de estrutura literais ou mesmo como argumentos para outras funções. Mas funções auxiliares ou usar um tipo diferente não são soluções que procuro.
var _ *int64 = pointer.Int64(64)
Respostas:
The Go Specification Language ( operadores de endereço faz) não permite tomar o endereço de uma constante numérica (não de um sem tipo nem de um digitado constante).
Para saber por que isso não é permitido, consulte a pergunta relacionada: Encontre o endereço da constante em go . Uma pergunta semelhante (da mesma forma não tem permissão para levar seu endereço): Como posso armazenar a referência ao resultado de uma operação em Go?
Suas opções (experimente tudo no Go Playground ):
1) Com
new()
Você pode simplesmente usar a
new()
função integrada para alocar um novo valor zeroint64
e obter seu endereço:Mas observe que isso só pode ser usado para alocar e obter um ponteiro para o valor zero de qualquer tipo.
2) Com variável auxiliar
O mais simples e recomendado para elementos diferentes de zero é usar uma variável auxiliar cujo endereço pode ser obtido:
3) Com função auxiliar
Nota: As funções auxiliares para adquirir um ponteiro para um valor diferente de zero estão disponíveis em minha
github.com/icza/gox
biblioteca, nogox
pacote, portanto, você não precisa adicioná-las a todos os seus projetos onde precisar.Ou, se você precisar disso muitas vezes, pode criar uma função auxiliar que aloca e retorna um
*int64
:E usando:
Observe que, na verdade, não alocamos nada, o compilador Go fez isso quando retornamos o endereço do argumento da função. O compilador Go executa a análise de escape e aloca variáveis locais no heap (em vez da pilha) se elas podem escapar da função. Para obter detalhes, consulte O retorno de uma fatia de um array local em uma função Go é seguro?
4) Com uma função anônima de uma linha
Ou como uma alternativa (mais curta):
5) Com literal de fatia, indexação e obtenção de endereço
Se você quiser
*SomeField
ser diferente de0
, então precisa de algo endereçável.Você ainda pode fazer isso, mas é feio:
O que acontece aqui é que uma
[]int64
fatia é criada com um literal, tendo um elemento (5
). E é indexado (0º elemento) e o endereço do 0º elemento é obtido. No fundo, uma matriz de[1]int64
também será alocada e usada como matriz de apoio para a fatia. Portanto, há muito clichê aqui.6) Com um literal de estrutura auxiliar
Vamos examinar a exceção aos requisitos de endereçamento:
Isso significa que pegar o endereço de um literal composto, por exemplo, um literal de estrutura está ok. Se fizermos isso, teremos o valor da estrutura alocado e um ponteiro obtido para ele. Mas se for assim, outro requisito se tornará disponível para nós: "seletor de campo de um operando de estrutura endereçável" . Portanto, se o literal de estrutura contém um campo do tipo
int64
, também podemos obter o endereço desse campo!Vamos ver essa opção em ação. Usaremos este tipo de estrutura de wrapper:
E agora podemos fazer:
Observe que este
significa o seguinte:
Mas podemos omitir o parêntese "externo", pois o operador de endereço
&
é aplicado ao resultado da expressão do seletor .Observe também que em segundo plano acontecerá o seguinte (esta também é uma sintaxe válida):
7) Com literal de estrutura anônima auxiliar
O princípio é o mesmo do caso nº 6, mas também podemos usar um literal de estrutura anônima, portanto, nenhuma definição de tipo de estrutura auxiliar / wrapper é necessária:
fonte
instance
objetos diferentes apontariam para doisint64
s diferentes . Mas parece atender às intenções dos OPs de forma adequada&[]int64{2}[0]
acho que, com base na descrição das constantes em blog.golang.org/constants, isso deve funcionar como&0
.instance
objetos diferentesint64
apontassem para o mesmo e um modificasse o objeto apontado, ambos mudariam. E se agora você usar o mesmo literal para criar um terceiroinstance
? O mesmo endereço agora apontaria para umint64
valor diferente ... então um endereço diferente deve ser usado, mas então por que usar o mesmo no caso dos primeiros 2?Use uma função que retorna um endereço de uma variável int64 para resolver o problema.
fonte