Почему я получаю «отсутствующий параметр для расширенной функции» в одном случае, а не в другом? - PullRequest
22 голосов
/ 15 января 2011

Дело это работает:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (println(_))

Принимая во внимание, что это не так:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception(_.toString))

Компиляция заканчивается с этой ошибкой:

error: missing parameter type for expanded function ((x$4) => x$4.toString)

Теперь, если я напишу это так, он снова скомпилируется:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (s => throw new Exception(s.toString))

Я уверен, что есть разумное объяснение;)

Ответы [ 2 ]

28 голосов
/ 15 января 2011

Этот вопрос уже был рассмотрен в связанном вопросе . Подчеркивания простираются наружу до ближайшего закрытия Expr: выражения верхнего уровня или выражения в скобках.

(_.toString) - это выражение в скобках. Следовательно, аргумент, который вы передаете Exception в случае ошибки, после раскрытия представляет собой полную анонимную функцию (x$1) => x$1.toString типа A <: Any => String, тогда как Exception ожидает String.

В случае println, _ сам по себе не имеет синтаксической категории Expr, но (println (_)), так что вы получите ожидаемый (x$0) => println(x$0).

9 голосов
/ 16 января 2011

Разница в том, означает ли _ весь параметр или является частью выражения.В зависимости от того, что входит в одну из следующих категорий:

Частично примененная функция

Seq(fromDir, toDir) find (!_.isDirectory) foreach (println(_))

переводится в

Seq(fromDir, toDir) find (!_.isDirectory) foreach ((x$1) => println(x$1))

Параметр анонимной функции

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception(_.toString))

переводится как

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception((x$1) => x$1.toString))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...