Pesquisei no Google para encontrar as diferenças entre a case class
e a class
. Todo mundo menciona que, quando você deseja fazer a correspondência de padrões na classe, use a classe de caso. Caso contrário, use classes e também mencione algumas vantagens extras, como iguais e substituição de código de hash. Mas essas são as únicas razões pelas quais se deve usar uma classe de caso em vez de classe?
Acho que deve haver uma razão muito importante para esse recurso no Scala. Qual é a explicação ou existe um recurso para aprender mais sobre as classes de caso Scala?
fonte
Tecnicamente, não há diferença entre uma classe e uma classe de caso - mesmo que o compilador otimize algumas coisas ao usar classes de caso. No entanto, uma classe de caso é usada para eliminar a placa da caldeira para um padrão específico, que está implementando tipos de dados algébricos .
Um exemplo muito simples de tais tipos são as árvores. Uma árvore binária, por exemplo, pode ser implementada assim:
Isso nos permite fazer o seguinte:
Observe que as árvores constroem e desconstroem (através da correspondência de padrões) com a mesma sintaxe, que também é exatamente como elas são impressas (menos espaços).
E eles também podem ser usados com mapas ou conjuntos de hash, pois eles têm um hashCode válido e estável.
fonte
(Você já mencionou tudo, exceto o último).
Essas são as únicas diferenças para as classes regulares.
fonte
Ninguém mencionou que as classes de casos também são instâncias
Product
e, portanto, herdam esses métodos:onde the
productArity
retorna o número de parâmetros de classe,productElement(i)
retorna o i- ésimo parâmetro eproductIterator
permite iterar através deles.fonte
Ninguém mencionou que as classes de caso têm
val
parâmetros construtores, mas esse também é o padrão para as classes regulares (o que eu acho que é uma inconsistência no design do Scala). Dario sugeriu isso onde ele notou que eles são " imutáveis ".Observe que você pode substituir o padrão acrescentando um argumento a cada construtor
var
para classes de caso. No entanto, fazendo classes case mutável faz com que os seusequals
ehashCode
métodos para ser variante tempo. [1]O sepp2k já mencionou que as classes de caso geram
equals
ehashCode
métodos automaticamente .Além disso, ninguém mencionou que as classes de caso criam automaticamente um complemento
object
com o mesmo nome da classe, que contémapply
eunapply
métodos. Oapply
método permite construir instâncias sem preceder comnew
. Ounapply
método extrator permite a correspondência de padrões mencionada por outros.Além disso, o compilador otimiza a velocidade de
match
-case
correspondência de padrão para as classes de casos [2].[1] Classes de casos são legais
[2] Classes de casos e extratores, página 15 .
fonte
A construção de classe de caso no Scala também pode ser vista como uma conveniência para remover alguns clichês.
Ao construir uma classe de caso, o Scala fornece o seguinte.
apply
método que você pode usar como método de fábrica. Você obtém a vantagem sintática do açúcar por não precisar usar a nova palavra-chave.Como a classe é imutável, você obtém acessadores, que são apenas as variáveis (ou propriedades) da classe, mas sem mutadores (portanto, não há capacidade de alterar as variáveis). Os parâmetros do construtor estão automaticamente disponíveis para você como campos públicos somente leitura. Muito mais agradável de usar do que a construção do Java bean.
hashCode
,equals
etoString
métodos, por padrão eoequals
método compara um objeto estruturalmente. Umcopy
método é gerado para poder clonar um objeto (com alguns campos tendo novos valores fornecidos ao método).A maior vantagem, como mencionado anteriormente, é o fato de que você pode padronizar a correspondência nas classes de caso. A razão para isso é porque você obtém o
unapply
método que permite desconstruir uma classe de caso para extrair seus campos.Em essência, o que você obtém do Scala ao criar uma classe de caso (ou um objeto de caso, se sua classe não aceita argumentos) é um objeto único que serve ao propósito de fábrica e de extrator .
fonte
copy
método pode modificar os campos:val x = y.copy(foo="newValue")
Além do que as pessoas já disseram, existem algumas diferenças mais básicas entre
class
ecase class
1.
Case Class
não precisa explícitonew
, enquanto a classe precisa ser chamada comnew
2.Por parâmetros de construtores padrão são privados
class
, enquanto seu público emcase class
3.
case class
comparar-se por valorfonte
De acordo com a documentação da Scala :
Outro recurso da palavra-chave case é que o compilador gera automaticamente vários métodos para nós, incluindo os métodos familiares toString, equals e hashCode em Java.
fonte
Classe:
Mas se usarmos o mesmo código, mas usarmos a classe de caso:
Classe de pessoa:
Correspondência de padrões:
objeto: singleton:
fonte
Para ter o melhor entendimento do que é uma classe de caso:
vamos assumir a seguinte definição de classe de caso:
e faça o seguinte no terminal:
O Scala 2.12.8 produzirá:
Como podemos ver, o compilador Scala produz uma classe regular
Foo
e um objeto complementarFoo
.Vamos percorrer a classe compilada e comentar o que temos:
Foo
classe, imutável:scala.Product
característica de implementação :scala.Equals
característica para tornar instâncias de classe de caso comparáveis à igualdade por==
:java.lang.Object.hashCode
por obedecer ao contrato equals-hashcode:java.lang.Object.toString
:new
palavra-chave:Objeto Foo: - método
apply
para instanciação semnew
palavra-chave:unupply
para usar a classe de caso Foo na correspondência de padrões:scala.runtime.AbstractFunction2
para fazer esse truque:tupled
from object retorna uma função para criar um novo Foo aplicando uma tupla de 2 elementos.Portanto, a aula de caso é apenas açúcar sintático.
fonte
Diferentemente das classes, as classes de caso são usadas apenas para armazenar dados.
As classes de caso são flexíveis para aplicativos centrados em dados, o que significa que você pode definir campos de dados na classe de caso e definir lógica de negócios em um objeto complementar. Dessa forma, você está separando os dados da lógica de negócios.
Com o método de cópia, você pode herdar uma ou todas as propriedades necessárias da origem e alterá-las conforme desejar.
fonte
Ninguém mencionou que o objeto complementar da classe de caso tem
tupled
defesa, que possui um tipo:O único caso de uso que posso encontrar é quando você precisa construir uma classe de caso a partir da tupla, por exemplo:
Você pode fazer o mesmo, sem tupla, criando objeto diretamente, mas se seus conjuntos de dados expressos como lista de tupla com aridade 20 (tupla com 20 elementos), pode estar usando tupla, é sua escolha.
fonte
Uma classe de caso é uma classe que pode ser usada com a
match/case
instruçãoVocê vê que
case
é seguido por uma instância da classe Fun cujo segundo parâmetro é um Var. Essa é uma sintaxe muito agradável e poderosa, mas não pode funcionar com instâncias de nenhuma classe; portanto, existem algumas restrições para as classes de caso. E se essas restrições forem obedecidas, é possível definir automaticamente código hash e iguais.A frase vaga "um mecanismo de decomposição recursiva via correspondência de padrões" significa apenas "ele trabalha com
case
". (De fato, a instância seguida pormatch
é comparada com (comparada com) a instância a seguircase
, Scala precisa decompor os dois e decompor recursivamente do que eles são feitos.)Para que classes de casos são úteis? O artigo da Wikipedia sobre tipos de dados algébricos fornece dois bons exemplos clássicos, listas e árvores. O suporte para tipos de dados algébricos (incluindo saber como compará-los) é obrigatório para qualquer linguagem funcional moderna.
Para quais classes de caso não são úteis? Alguns objetos têm estado, o código como
connection.setConnectTimeout(connectTimeout)
não é para classes de caso.E agora você pode ler A Tour of Scala: Case Classes
fonte
Eu acho que no geral todas as respostas deram uma explicação semântica sobre classes e classes de casos. Isso pode ser muito relevante, mas todo iniciante no scala deve saber o que acontece quando você cria uma classe de caso. Eu escrevi esta resposta, que explica a classe de caso em poucas palavras.
Todo programador deve saber que, se estiver usando alguma função pré-criada, estará escrevendo um código comparativamente menos, o que lhes permitirá dar o poder de escrever o código mais otimizado, mas o poder vem com grandes responsabilidades. Portanto, use funções pré-construídas com muito cuidado.
Alguns desenvolvedores evitam escrever classes de caso devido a 20 métodos adicionais, que você pode ver desmontando o arquivo de classe.
Por favor, consulte este link se você quiser verificar todos os métodos dentro de uma classe caso .
fonte
fonte
Alguns dos principais recursos
case classes
estão listados abaixonew
palavra-chave.Exemplo de código scala no scala fiddle, retirado dos documentos do scala.
https://scalafiddle.io/sf/34XEQyE/0
fonte