Разница между объектом дела и объектом

226

Есть ли разница между объектом case и объектом в scala?

Войцех Дурчинский
источник
3
У него есть точка - необязательно иметь объект case, чтобы иметь возможность сопоставления с образцом. Я думаю, что это не было рассмотрено в предыдущем вопросе ...
axel22
3
Я думал, что будет разница в поведении сопоставления с образцом, но и объект case, и обычный объект ведут себя одинаково в AFAIK сопоставления с образцом. Довольно сложно найти какую-либо информацию об объектах дела, поэтому я с нетерпением жду, чтобы кто-то нас просветил.
Возраст Mooij
4
Нет необходимости использовать caseдля сопоставления с образцом, это просто сахар. Реализация unapplyсебя делает работу.
Рафаэль
1
Принятый ответ просто не отвечает на вопрос, как обсуждалось в комментариях к нему. Слишком поздно, чтобы что-то изменить, но следует отметить.
Брюс
Еще не поздно отредактировать принятый ответ. Редактирование будет рассмотрено и, если необходимо, принято.
C4stor

Ответы:

111

Классы Case отличаются от обычных классов тем, что они получают:

  1. поддержка сопоставления с образцом
  2. реализации по умолчанию equalsиhashCode
  3. стандартные реализации сериализации
  4. более симпатичная реализация по умолчанию toString, и
  5. небольшое количество функциональности, которую они получают от автоматического наследования scala.Product.

Сопоставление с образцом, equals и hashCode не имеют большого значения для одиночных игр (если вы не делаете что-то действительно вырожденное), так что вы в значительной степени просто получаете сериализацию, хороший toStringи некоторые методы, которые вы, вероятно, никогда не будете использовать.

Дэйв Гриффит
источник
46
Пункты 3 и 4 этого ответа - правильная разница между объектами дела и объектами. Точки 1 и 2 не имеют значения для одноэлементных объектов. И одноэлементные объекты всегда являются продуктами с арностью 0, поэтому пункт 5 также не имеет значения.
Войцех Дурчиньский,
86
Этот пост увековечивает миф о objectтом же, что и синглтон. Это не. Скорее, это именно то, что он говорит, это объект, то есть объявление и создание экземпляра в одном. Это ограничивает objectодин экземпляр, если он определен в области действия пакета, что фактически делает его одноэлементным, но только если он определен В ЭТОЙ ОБЛАСТИ. Если он определен внутри класса, вы можете иметь столько же экземпляров, сколько и сам класс (он создается лениво, поэтому не обязательно 1-1). И эти внутренние объекты вполне можно использовать в качестве ключей хеширования, что делает значение по умолчанию equals / hashCode очень разумным.
nilskp
66
Вопрос case objectне в классе, почему это правильный ответ?
Ixx
10
Это не отвечает на вопрос. Этот ответ касается разницы между case classи class. Вопрос о разнице между case objectа object.
MK
6
@ C4stor Ответ не говорит об этом, хотя. Объект не является классом. Принимая во внимание, что классы прецедентов изобилуют магией за кулисами, учитывая различные крайние случаи и сложности Scala, нет никаких оснований просто предполагать, что единственная разница между стандартным объектом Scala и объектом прецедента объясняется тем, что мы знаем о разнице между стандартными классами и тематическими классами. Этот ответ даже не касается формулировки вопроса.
Брюс
137

Вот одно отличие - объекты case расширяют эту Serializableчерту, поэтому их можно сериализовать. Обычные объекты не могут по умолчанию:

scala> object A
defined module A

scala> case object B
defined module B

scala> import java.io._
import java.io._    

scala> val bos = new ByteArrayOutputStream                                            
bos: java.io.ByteArrayOutputStream =  

scala> val oos = new ObjectOutputStream(bos)                                          
oos: java.io.ObjectOutputStream = java.io.ObjectOutputStream@e7da60                   

scala> oos.writeObject(B)

scala> oos.writeObject(A)
java.io.NotSerializableException: A$
axel22
источник
15
Я думаю, что объекты case могут быть сериализованы - это самое большое отличие от обычных объектов, особенно в сетевой коммуникации между актерами
爱国者
14
Добавление extends Serializableдолжно сделать то же самое, хотя.
nilskp
36
scala> object foo

определенный объект foo

scala> case object foocase

определенный объект

Разница в сериализации:

scala> foo.asInstanceOf[Serializable]

java.lang.ClassCastException: foo $ нельзя преобразовать в scala.Serializable
... 43 elided

scala> foocase.asInstanceOf[Serializable]

res1: Serializable = foocase

разница строк:

scala> foo

res2: foo.type = foo $ @ 7bf0bac8

scala> foocase

res3: foocase.type = foocase

Минни
источник
2

объекты case неявно поставляются с реализациями методов toString, equals и hashCode, но простые объекты этого не делают. объекты case могут быть сериализованы, а простые объекты - нет, что делает объекты case очень полезными в качестве сообщений с помощью Akka-Remote. Добавление ключевого слова case перед ключевым словом object делает объект сериализуемым.

Prashant_Sharma
источник
0

Это похоже на case classи class, мы просто используем case objectвместо, case classкогда нет никаких полей, представляющих дополнительную информацию о состоянии.

wineway
источник
0

Мы знаем объекты и «класс дела» раньше. Но «объект case» представляет собой смесь обоих, то есть он представляет собой синглтон, похожий на объект и имеющий множество шаблонов, как в классе case. Разница лишь в том, что шаблон сделан для объекта, а не для класса.

объекты case не будут поставляться со следующими:

Применить, Отменить методы. здесь нет методов копирования, так как это единственный. Нет метода для сравнения структурного равенства. Также нет конструктора.

Дживан Кишоре
источник