Scala: для создания экземпляра класса case требуется применить метод в компаньоне?

Приведенный ниже код определяет тип List и две реализации классов case, один из которых представляет пустой список, а Cons для создания фактического списка.

sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]

object List {
  ...
  def apply[A](as: A*): List[A] = {
    if (as.isEmpty) Nil
    else Cons(as.head, apply(as.tail: _*))
  }
  val example = Cons(1, Cons(2, Cons(3, Nil)))
}

верно ли мое предположение, что список создается рекурсивным методом применения, описанным выше, когда выполняется val example = ....

если это так. подпись для создания Cons - Cons(head, tail), где, поскольку подпись приложения несовместима variad def apply[A](as: A*): List[A], как scala на самом деле делает вывод, что val example будет List(1, 2, 3, Nil)


person Somasundaram Sekar    schedule 28.09.2014    source источник


Ответы (1)


Когда ты говоришь

class Foo(s: String, i: Int)

в scala он генерирует класс Foo с конструктором, принимающим String и Int.

Это почти то же самое, что класс java, объявленный как

public class Foo {
   public Foo(String s, int i) {
       ...
   }
}

С классами case компилятор предоставляет дополнительные возможности, такие как сопутствующий объект с методом apply по умолчанию, принимающим те же параметры, что и конструктор.

Вот почему вы можете напрямую вызывать Cons(head, tail) без явного определения конструктора.

person Gabriele Petronella    schedule 28.09.2014
comment
как насчет val example2 = List(1,2,3), на самом деле я пытаюсь понять, как создается экземпляр Cons, поскольку нет конструктора, в котором я говорю, что нужно объединить голову и хвост, чтобы создать Cons[Int], как scala достигает этого. - person Somasundaram Sekar; 28.09.2014
comment
Я не уверен, что понимаю вопрос. Const — это класс case, поэтому у него есть конструктор, принимающий A и List[A]. Вы явно вызываете его в ветке else метода apply. - person Gabriele Petronella; 28.09.2014
comment
Если бы вы могли простить моего новичка, я попытаюсь объяснить. Как вы упомянули, у Cons есть пустой конструктор, поскольку у него нет тела. Apply вызывает Cons рекурсивно, чтобы создать его экземпляр. Но параметры применения и конструктора Cons отличаются. - person Somasundaram Sekar; 28.09.2014
comment
Нет, Cons имеет неявный конструктор, принимающий именно эти параметры. Проверьте мой обновленный ответ - person Gabriele Petronella; 28.09.2014