Как преодолеть предел classа Case Scala из 22 полей?

Классы classов Scala имеют предел из 22 полей в конструкторе. Я хочу превзойти этот предел, есть ли способ сделать это с наследованием или композицией, которая работает с classами classов?

5 Solutions collect form web for “Как преодолеть предел classа Case Scala из 22 полей?”

Совсем недавно (октябрь 2016 года, через шесть лет после OP) сообщение в блоге « Scala и 22 » от Ричарда Даллауэя исследует этот предел:

Еще в 2014 году, когда была выпущена Scala 2.11, было устранено важное ограничение:

Case classes with > 22 parameters are now allowed. 

Это может заставить вас думать, что в Scala нет 22 ограничений, но это не так. Предел живет в функциях и кортежах .

Исправление ( PR 2305 ), введенное в Scala 2.11, устранило ограничение для вышеуказанных общих сценариев: построение classов случаев, доступ к полям (включая копирование) и сопоставление шаблонов ( исключение краевых случаев ).

Он сделал это, опуская unapply и tupled для classов classов выше 22 полей.
Другими словами, предел для Function22 и Tuple22 все еще существует.

Работа над лимитом (post Scala 2.11)

Существует два распространенных трюка, чтобы обойти этот предел.

  • Первый – использовать вложенные кортежи .
    Хотя верно, что кортеж не может содержать более 22 элементов, каждый элемент может быть кортежем

  • Другой общий трюк заключается в использовании гетерогенных списков (HLists), где нет 22 предела.

Если вы хотите использовать classы case, вам может быть лучше использовать бесформенную реализацию HList. Мы создали библиотеку Slickless, чтобы сделать это проще. В частности, недавний метод mappedWith конвертирует между бесформенными HLists и classами case. Это выглядит так:

 import slick.driver.H2Driver.api._ import shapeless._ import slickless._ class LargeTable(tag: Tag) extends Table[Large](tag, "large") { def a = column[Int]("a") def b = column[Int]("b") def c = column[Int]("c") /* etc */ def u = column[Int]("u") def v = column[Int]("v") def w = column[Int]("w") def * = (a :: b :: c :: /* etc */ :: u :: v :: w :: HNil) .mappedWith(Generic[Large]) } 

Полный пример с 26 столбцами в базе данных Slickless.

Эта проблема будет исправлена ​​в Scala 2.11.

Создайте нормальный class, который действует как class case.

Я все еще использую scala 2.10.X, так как это последняя версия, поддерживаемая Spark, а в Spark-SQL я активно использую classы case.

Обходной путь для case classes с более чем 22 полями:

 class Demo(val field1: String, val field2: Int, // .. and so on .. val field23: String) extends Product //For Spark it has to be Serializable with Serializable { def canEqual(that: Any) = that.isInstanceOf[Demo] def productArity = 23 // number of columns def productElement(idx: Int) = idx match { case 0 => field1 case 1 => field2 // .. and so on .. case 22 => field23 } } 

Интересно, что ваш конструктор загружен, но вы можете упаковать связанные значения в собственный class case.

Поэтому, хотя вы можете

 case class MyClass(street: String, city: String, state: String, zip: Integer) 

вы можете сделать это

 case class MyClass(address: Address) 

У вас есть и другие варианты:

  • Групповые элементы в кортежи
  • Создайте свой собственный признак Function23 (или что-то еще)
  • Использовать карри

ОБНОВЛЕНИЕ: Как отмечали другие, это уже не проблема после выпуска Scala 2.11, хотя я бы с сомнением использовал термин «исправить». Тем не менее, «Catch 22», если хотите, иногда по-прежнему появляется в сторонних библиотеках Scala.

Когда у вас есть много значений, это обычно признак того, что ваш дизайн должен быть переделан в любом случае.

Формируйте прерывистые classы classов, которые затем объединяются в более крупные. Это также упрощает понимание кода, обоснование и поддержку кода. Как и в обход этой проблемы у вас есть.

Например, если бы я хотел хранить данные пользователя, я мог бы это сделать ….

 case class User(name: Name, email: String) case class Name(first: String, last: String) 

С такими немногими вещами это, конечно, не было бы необходимо. Но если у вас есть 22 вещи, которые вы пытаетесь втиснуть в один class, вы все равно захотите сделать такой class прерывистого classа.

  • Равномерность classа в Apache Spark
  • Добавить банки в Spark Job - spark-submit
  • Как изменить параметры конструктора scala по умолчанию на private val?
  • Scala 2.8 breakOut
  • Что такое «контекст» в Scala?
  • Scala: Почему mapValues ​​создает представление и есть ли стабильные альтернативы?
  • Два способа определения функций в Scala. В чем разница?
  • Как использовать java.String.format в Scala?
  • Scala: абстрактные типы против дженериков
  • Получить экземпляр объекта-компаньона с новым API-интерфейсом Scala reflection
  • (Почему) нам нужно вызвать кеш или сохранить на RDD
  • Interesting Posts

    Windows Update не может установить пакет обновления 1 (SP1) для Windows Vista

    Могу ли я просматривать отчеты об ошибках других людей (Apple)?

    Препроцессор дампа GCC определяет

    Как использовать переменную на стороне замены оператора замены Perl?

    найти путь текущей папки – cmd

    Есть ли бесплатный инструмент, который позволит мне печатать на PDF-файлах, а затем сохранять или, по крайней мере, печатать их?

    Msgstr “wait_fences: не удалось получить ответ: 10004003”?

    Как понизить Chrome от dev до бета-канала, не теряя моего профиля?

    Как записывать и воспроизводить http-взаимодействия?

    Шифрование и дешифрование строки в C #

    Как работает Connectify?

    Как я могу изменить внешний вид терминала (Linux), когда я подключу SSH к удаленной машине?

    Как восстановить библиотеки в iTunes с помощью файлов на iPod Touch?

    Как удалить повторяющуюся строку на основе некоторых столбцов

    Папка SRC в Eclipse пуста (class MainActivity не создан) после создания нового проекта андроида с использованием Eclipse

    Давайте будем гением компьютера.