Quais são alguns exemplos de casos de uso para literais de símbolo em Scala?
93
O uso de literais de símbolo não é imediatamente claro pelo que li no Scala. Alguém se importaria em compartilhar alguns usos do mundo real?
Existe um idioma Java específico sendo coberto por literais de símbolo? Quais linguagens têm construções semelhantes? Venho de uma experiência em Python e não tenho certeza se há algo análogo nessa linguagem.
O que me motivaria a usar 'HelloWorld vs "HelloWorld"?
Em termos de Java, os símbolos são strings internas. Isso significa, por exemplo, que a comparação de igualdade de referência ( eqem Scala e ==em Java) dá o mesmo resultado que a comparação de igualdade normal ( ==em Scala e equalsem Java): 'abcd eq 'abcdretornará verdadeiro, enquanto "abcd" eq "abcd"pode não, dependendo dos caprichos da JVM (bem, deveria para literais, mas não para strings criadas dinamicamente em geral).
Outras linguagens que usam símbolos são Lisp (que usa 'abcdcomo Scala), Ruby ( :abcd), Erlang e Prolog ( abcd; eles são chamados de átomos em vez de símbolos).
Eu usaria um símbolo quando não me importasse com a estrutura de uma string e o usaria puramente como um nome para algo. Por exemplo, se eu tiver uma tabela de banco de dados representando CDs, que inclui uma coluna chamada "preço", não me importo se o segundo caractere em "preço" é "r" ou sobre a concatenação dos nomes das colunas; portanto, uma biblioteca de banco de dados em Scala poderia razoavelmente usar símbolos para nomes de tabelas e colunas.
Provavelmente vale a pena lembrar que == em Scala faz a coisa .equals, então realmente a diferença seria quando usar o método "eq" que faz referência a igualdade. Um bônus, porém, é que a comparação entre os símbolos é extremamente barata.
Calum
@Calum, assim como a comparação entre duas strings. Estagiários de Java (mais ou menos) todas as strings.
Elazar Leibovich
4
@Elazar: Isso é verdade? Fiquei com a impressão de que Java apenas internava literais (ou seja, quase todas as strings em exemplos triviais e quase nenhuma string em software de produção). Dito isso, os casos de uso de símbolos geralmente são valores literais (duvido que você os construa do zero com frequência), portanto, sem dúvida, a principal vantagem que você obtém é apenas um tipo mais descritivo.
Calum
1
@Elazar Eles não são, porque os símbolos podem contar com seu valor sendo internados, enquanto que com Strings é opcional e pode otimizar alguns casos de uso. Os símbolos são mais como Enums criados dinamicamente do que qualquer coisa. Elaborei sobre isso na resposta que vinculei em minha última resposta; por favor leia para mais.
Calum
3
Então, "olá, mundo!" é uma coleção sequencial de personagens, enquanto 'helloWorld é um valor amigável para as pessoas, em vez de 14392.
CW Holeman II
26
Se você tiver strings simples que representam, por exemplo, nomes de métodos no código, que talvez sejam passados adiante, você não está transmitindo as coisas de maneira adequada. Este é um tipo de problema de limite de dados / código, nem sempre é fácil traçar a linha, mas se disséssemos que naquele exemplo esses nomes de métodos são mais código do que dados, então queremos algo para identificar claramente que .
Um símbolo literal entra em jogo onde ele diferencia claramente qualquer dado de string antigo com uma construção sendo usada no código. Ele está realmente lá onde você deseja indicar, não são apenas alguns dados de string, mas de alguma forma parte do código. A ideia de ser coisas como o seu IDE o destacaria de maneira diferente e, com as ferramentas, você poderia refatorá-las, em vez de fazer uma busca / substituição de texto.
Esta é uma explicação útil. Isso me faz pensar em termos de alternativas para enums - o que pode ser desajeitado
javadba
2
Python mantém uma tabela global interna de "strings internadas" com os nomes de todas as variáveis, funções, módulos, etc. Com esta tabela, o interpretador pode fazer buscas e otimizações mais rápidas. Você pode forçar esse processo com a internfunção ( sys.internem python3).
Além disso, o Java e o Scala usam automaticamente "strings internas" para pesquisas mais rápidas. Com o scala, você pode usar o internmétodo para forçar o interior de uma string, mas esse processo não funciona com todas as strings. Os símbolos se beneficiam com a garantia de internação, portanto, uma única verificação de igualdade de referência é suficiente para provar igualdade ou desigualdade.
Se você tiver strings simples que representam, por exemplo, nomes de métodos no código, que talvez sejam passados adiante, você não está transmitindo as coisas de maneira adequada. Este é um tipo de problema de limite de dados / código, nem sempre é fácil traçar a linha, mas se disséssemos que naquele exemplo esses nomes de métodos são mais código do que dados, então queremos algo para identificar claramente que .
Um símbolo literal entra em jogo onde ele diferencia claramente qualquer dado de string antigo com uma construção sendo usada no código. Ele está realmente lá onde você deseja indicar, não são apenas alguns dados de string, mas de alguma forma parte do código. A ideia de ser coisas como o seu IDE o destacaria de maneira diferente e, com as ferramentas, você poderia refatorá-las, em vez de fazer uma busca / substituição de texto.
Este link discute isso muito bem.
fonte
Python mantém uma tabela global interna de "strings internadas" com os nomes de todas as variáveis, funções, módulos, etc. Com esta tabela, o interpretador pode fazer buscas e otimizações mais rápidas. Você pode forçar esse processo com a
intern
função (sys.intern
em python3).Além disso, o Java e o Scala usam automaticamente "strings internas" para pesquisas mais rápidas. Com o scala, você pode usar o
intern
método para forçar o interior de uma string, mas esse processo não funciona com todas as strings. Os símbolos se beneficiam com a garantia de internação, portanto, uma única verificação de igualdade de referência é suficiente para provar igualdade ou desigualdade.fonte