Об использовании метода scala def apply

#scala

#scala

Вопрос:

 val B = new {
  def apply : { val a : Int } => { val b : String ; val c : Int } =
    x => new { val b = "Hi" ; val c = 0 }
}
  

Я не могу понять этот код.
Что он делает?
И как я могу использовать apply of B. Кажется, у B нет b или c..

Комментарии:

1. Предоставленный вами код не компилируется. Неясно, что вы хотите сделать.

2. Выполняется ли компиляция с 2.11

Ответ №1:

Здесь компилируется просто отлично.

 scala> val B = new {
    |   def apply : { val a : Int } => { val b : String ; val c : Int } =
    |     x => new { val b = "Hi" ; val c = 0 }
    | }
B: AnyRef{def apply: AnyRef{val a: Int} => AnyRef{val b: String; val c: Int}} = $anon$1@464bee09
  

Подпись довольно понятна, однако к чему-то вам придется привыкнуть.

 AnyRef
  

анонимный объект. Аналогично объекту Java

   {def apply: AnyRef{val a: Int} => AnyRef{val b: String; val c: Int}}
  

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

   def apply: AnyRef{val a: Int} => AnyRef{val b: String; val c: Int}
  

Он возвращает => , также известное как Function1 , что является сокращением от функции
объект, принимающий один аргумент. Здесь он принимает аргумент типа AnyRef{val a:
Int}
и возвращает объект типа AnyRef{val b: String; val c: Int} .

Тот же комментарий, что и выше, применим к природе структурной типизации.

Как я бы рекомендовал писать этот код:

 case class Foo(b: String, c: Int)
val B: Int => Foo = { x => Foo("Hi", 0) }
  

Комментарии:

1. «анонимный объект» : не является ли это скорее объектом, основанным на объявлении анонимного типа?

2. Чем они отличаются?

3. «анонимный объект» подразумевает, что у объекта нет имени. Эта информация избыточна. Только методы, пакеты, объекты пакета, черты, классы и синглтоны object имеют имена, «обычные» объекты никогда не имеют имен, поэтому они всегда анонимны.