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

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

Совсем недавно (октябрь 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а.

  • API Карт Google v2 SupportMapFragment внутри ScrollView - пользователи не могут прокручивать карту по вертикали
  • Scala: Почему mapValues ​​создает представление и есть ли стабильные альтернативы?
  • Почему компилятор Scala не применяет оптимизацию хвостового вызова, если только метод не является окончательным?
  • Как вычислить суммарную сумму, используя Spark
  • Как я могу использовать объект singleton Scala в Java?
  • Как запросить столбцы данных JSON, используя Spark DataFrames?
  • Как я могу прочитать большой файл CSV с classом Scala Stream?
  • Apache Spark: map vs mapPartitions?
  • Итерация над compilationами Java в Scala
  • `def` vs` val` vs `lazy val` в Scala
  • В Scala, что означает «val a: A = _» (подчеркивание), означает?
  • Interesting Posts

    Добавление уравнения регрессионной линии и R2 на графике

    Visual Studio показывает ошибки IntelliSense, но компиляции решений

    Скопируйте файлы с определенным расширением в папку

    Могу ли я найти точный тип оперативной памяти, не заглядывая внутрь?

    Как получить цветной режим vim для работы в vim под cygwin

    Firefox 4 отображает весь текст как «полужирный»,

    Как развернуть приложение на базе EJB на Tomcat

    Как изменить формат всех изображений в презентации PowerPoint 2010?

    Результат возврата от платформы javafx platform runter

    Как я могу запустить applescript с моего Mac с помощью ярлыка (без использования сторонних приложений)?

    Android: Как установить уровень масштабирования вида карты в радиусе 1 км вокруг моего текущего местоположения?

    jQuery UI Datepicker – выбор нескольких дат

    Hibernate Named Query Order По параметру

    Динамик Thinkpad отключается – проблема с Linux Codec?

    HTML5 iFrame Бесшовный атрибут

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