Ao escrever funções genéricas em Go, pode ser benéfico aceitar também tipos concretos. No entanto, isso representa um desafio ao tentar inicializar fatias de interfaces com novas instâncias desses tipos específicos.
Uma abordagem pode parecer lógica: definir dois parâmetros de tipo, um para o tipo de elemento slice (X) e outro para o tipo concreto (Y) a ser instanciado. No entanto, esta abordagem falha ao tentar atribuir uma instância de Y a um elemento do tipo X.
func Fill[X, Y any](slice []X){
for i := range slice {
slice[i] = new(Y) // not work!
}
}
Esse problema surge porque o compilador perde o relacionamento entre a interface X e sua implementação Y. Tanto X quanto Y são tratados como tipos distintos.
Para resolver isso, pode-se empregar uma operação de conversão explícita dentro da função:
func Fill[X, Y any](slice []X) {
for i := range slice {
slice[i] = any(*new(Y)).(X)
}
}
No entanto, esta abordagem desencadeia um pânico se Y não implementar X, o que ocorre em cenários como a tentativa de atribuir um *sync.Mutex (tipo de ponteiro) para sync.Locker.
Uma solução mais robusta e com segurança de tipo envolve a utilização de uma função construtora:
func Fill[X any](slice []X, f func() X) {
for i := range slice {
slice[i] = f()
}
}
Esta função aceita uma função construtora que retorna uma nova instância do tipo especificado. Isso permite a inicialização concisa e segura de fatias com instâncias de tipo concreto.
Nos casos em que o tipo concreto se destina a ser instanciado com um tipo de ponteiro, é importante observar esse new(Y) resultará em um valor nulo. Para contornar isso, pode-se ajustar a função construtora para retornar o valor correto do ponteiro, como func() X { return &sync.Mutex{} }.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3