Scala case class.type не принимает параметры

Я новичок в скале. Вот Models.scala, которую я пытаюсь написать. Когда я запускаю пакет sbt, он выдает ошибку

Models.scala:25: models.Session.Network.type does not take parameters
[error]         network : Network = Network() ,

Я не понимаю, почему происходит эта ошибка, я не передаю никаких параметров при выполнении Network(). Может кто-нибудь, пожалуйста, помогите мне

2 ответа

Вот небольшой код, который воспроизводит вашу проблему:

case class A(b:B = B(3, 5))

case class B(i: Int, j: Int)

object A {

  val B = "whatever"
}

На первой строке получаем

too many arguments for method apply: (index: Int)Char in class StringOps    

Что происходит, когда вы определяете сигнатуру класса case, вы одновременно определяете сигнатуру конструктора (когда вы вызываете с новым) и метод apply в объекте-компаньоне (когда вы вызываете без нового).

Когда вы вводите значение по умолчанию в качестве аргумента (Network() в вашем коде и B(3, 5) в моем), этот код будет скомпилирован как в контексте конструктора, так и метода apply объекта сопутствующего объекта.

Поскольку вы определили сопутствующий объект Session, метод apply автоматически добавляется в этот объект. Бывает, что Network () в вашем сопутствующем объекте означает Network.apply() для объекта Network, который вы там определили, и это означает строку B со значением "что угодно" в моем коде.

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

Вот пример:

case class A(b:B = bb)

case class B(i: Int, j: Int)

object bb extends B(3, 4)

object A {

  val bb = new B(7, 2)
}


object Test extends App {

  println(A())
  println(new A())

}

Бегущий тест распечатает

A(B(7,2))
A(B(3,4))

Для вашей конкретной проблемы есть простые обходные пути.

network: Network = models.Network(),

будет работать, очевидно, потому что тогда ясно, что вы хотите Network в пакете, а не в объекте Session.

network: Network = new Network(),

тоже будет работать, потому что с новым компилятор будет искать тип сети, а не значение сети. В сеансе сопутствующего объекта значение Network затеняется локальным объявлением, а тип Network - нет.

ИМО, прежний (models.Network) понятнее.


PS. Я проверил спецификацию и считаю, что это странное поведение соответствует этому. А именно, (5.3.2) метод apply генерируется внутри объекта-компаньона с тем же списком параметров, что и конструктор. Это включает значения по умолчанию, которые затем будут скомпилированы внутри объекта-компаньона.

Похоже, у вас могут быть некоторые переопределения импорта. У вас есть импорт Sessions._ где-нибудь в коде? Обратите внимание, что ваша ошибка относится к Session.Network, который является вашим неявным классом BSonDocument. Вы, вероятно, пытаетесь создать класс простого случая.

Попробуйте явно использовать сеть: network: models.Network = models.Network()

Другие вопросы по тегам