Isenção de responsabilidade: só joguei no Go por um dia agora, então há uma boa chance de eu ter perdido muito.
Alguém sabe por que não há suporte real para genéricos / modelos / whatsInAName no Go? Portanto, existe um genérico map
, mas é fornecido pelo compilador, enquanto um programador Go não pode escrever sua própria implementação. Com toda a conversa sobre tornar o Go o mais ortogonal possível, por que POSSO USAR um tipo genérico, mas não CRIAR um novo?
Especialmente quando se trata de programação funcional, existem lambdas e até fechamentos, mas com um sistema de tipo estático sem genéricos, como eu escrevo, bem, funções genéricas de ordem superior como filter(predicate, list)
? OK, listas vinculadas e similares podem ser feitas com o interface{}
sacrifício da segurança do tipo.
Como uma pesquisa rápida no SO / Google não revelou nenhum insight, parece que os genéricos, se houver, serão adicionados ao Go como uma reflexão tardia. Confio em Thompson para fazer muito melhor do que os caras do Java, mas por que manter os genéricos de fora? Ou eles estão planejados e ainda não foram implementados?
interface{}
sacrifica a segurança do tipo estático . No entanto, essa é uma reclamação um tanto estranha a ser feita ao mencionar o esquema no próximo parágrafo, pois o esquema normalmente não possui verificação de tipo estática.Respostas:
esta resposta você encontrará aqui: http://golang.org/doc/faq#generics
fonte
interface{}
, é o tipo de interface mais básico e todo objeto fornece. Se você criar um contêiner para contê-los, ele poderá aceitar qualquer objeto (não primitivo). Portanto, é muito semelhante a um contêiner armazenadoObjects
em Java.Go 2
Há um rascunho de design para genéricos em https://blog.golang.org/go2draft .
Go 1
Russ Cox, um dos veteranos do Go, escreveu um post intitulado The Generic Dilemma , no qual ele pergunta
Programadores lentos sendo o resultado de nenhum genérico, compiladores lentos são causados por C ++ como genéricos e tempos de execução lentos decorrem da abordagem de boxe-unboxing usada pelo Java.
A quarta possibilidade não mencionada no blog está seguindo a rota C #. Gerando o código especializado, como em C ++, mas em tempo de execução, quando necessário. Eu realmente gosto, mas o Go é muito diferente do C #, então isso provavelmente não é aplicável a todos os…
Devo mencionar que o uso da popular técnica Java 1.4, como a programação genérica em andamento,
interface{}
sofre exatamente os mesmos problemas do boxing-unboxing (porque é isso que estamos fazendo), além da perda de segurança do tipo tempo de compilação. Para tipos pequenos (como ints), o Go otimiza ointerface{}
tipo para que uma lista de ints que foram convertidas na interface {} ocupe uma área contígua da memória e ocupe apenas o dobro do espaço que as ints normais. Ainda há a sobrecarga das verificações de tempo de execução durante a transmissão a partir deinterface{}
. Referência .Todos os projetos que adicionam suporte genérico (existem vários e todos são interessantes) seguem uniformemente a rota C ++ de geração de código de tempo de compilação.
fonte
[]interface{}
uso 2x da RAM como[]int
. Embora verdade, tipos ainda menores (ou seja, byte) usam até 16x a RAM como[]byte
.Embora os genéricos não estejam embutidos no momento, existem várias implementações externas de genéricos para uso, que usam comentários em combinações com pequenos utilitários que geram código.
Aqui está uma dessas implementações: http://clipperhouse.github.io/gen/
fonte
Na verdade, de acordo com este post:
fonte
O polimorfismo paramétrico (genéricos) está sendo considerado no Go 2 .
Essa abordagem introduz o conceito de contrato , que pode ser usado para expressar restrições nos parâmetros de tipo:
Esse contrato poderia então ser usado assim:
Esta é uma proposta nesta fase.
Sua
filter(predicate, list)
função pode ser implementada com um parâmetro de tipo como este:Nesse caso, não há necessidade de restringir
T
.fonte