"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > ## Como inicializar fatias de interfaces com tipos concretos no Go?

## Como inicializar fatias de interfaces com tipos concretos no Go?

Publicado em 2024-11-10
Navegar:936

## How to Initialize Slices of Interfaces with Concrete Types in Go?

Inicialização genérica com interfaces e tipos concretos em Go

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.

Tentativas iniciais com vários parâmetros de tipo

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.

Usando conversão explícita

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.

Utilizando uma função construtora

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.

Evitando valores nulos

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{} }.

Tutorial mais recente Mais>

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