2017-02-08 10 views
1
Array("hi","there").map(println) 
Array("hi","there").map(s => println(s)) 
Array("hi","there").map(println(_)) 

Каждый из приведенных выше утверждений дает тот же результат, хотя в первых 2 аргумента к карте является функцией объекта, тогда как в последнем оно вызовы функций.Scala: аргумент для отображения является функцией ИЛИ вызов функции

0 Как есть Карта подходит для обработки как?

Подпись карты в TraversableLike класса, как это:

def map[B, That](f: scala.Function1[A, B])(implicit bf: scala.collection.generic.CanBuildFrom[Repr, B, That]) : That = { /* compiled code */ } 

ответ

2

Как карта способна обрабатывать как?

Он способен обрабатывать как, потому что компилятор создал method value для map, выполняя eta-expansion на println. В Scala есть различие между методами и функциями, где первое не имеет значения, что заставляет компилятор забирать лишнюю милю, чтобы заставить ее работать.

Компилятор после ETA-расширения на самом деле излучает:

Array("hi","there").map(s => println(s)) 

Matching свой второй пример. Реальный код более многословным, но означает то же самое:

scala.this.Predef.refArrayOps[String](
    scala.Array.apply[String]("hi", "there")(
    (ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String]))) 
    .map[Unit, Any]({((x: Any) => scala.this.Predef.println(x)) 
    })(scala.this.Array.canBuildFrom[Unit]((ClassTag.Unit: scala.reflect.ClassTag[Unit]))); 

Как @slouc сказал в комментариях, третий пример с использованием синтаксиса заполнитель desugered в s => println(s), что делает его эквивалентом на ваш второй пример.

В комплекте не столь важной стороне записки, так как println возвращается Unit, Array.foreach был бы более подходящим здесь:

Array("hi","there").foreach(println) 
+2

Я бы только добавить, что и первый и третий случай, трансформируются в 2 одной, а различные механизмы; первый из них - это расширение, как объяснил Юваль, а третий - простое сглаживание компилятора ('println (_)' и 's => println (s)' буквально одно и то же, прежнее - короткая форма последнего). Компилятор не сможет сопоставить первый пример с определением карты без eta-расширения, так как тип 'def foo = println' является' Unit', а не '(String) => Unit'. С другой стороны, 'def foo = println (_)' имеет тип '(String) => Unit' и, следовательно, 2-й и 3-й готовые к работе. – slouc

+1

@slouc Добавлено в ответ! –

 Смежные вопросы

  • Нет связанных вопросов^_^