Подчеркивание в именованных аргументах
Может кто-нибудь объяснить мне, что именно здесь происходит? Я не полностью вдаюсь в это прямо сейчас:
val s = Seq(1D,2D,3D,4D)
case class WithUnit(value: Double, unit: String)
s map { WithUnit(_,"cm") } // works
s map { WithUnit(value = _ , unit = "cm") } // error: missing parameter type for expanded function ((x$2) => value = x$2)
Я думаю, что компилятор не может вывести тип параметра, потому что я написал имя аргумента. Но почему нет? Это не должно быть сложнее только из-за указания имени аргумента?!
Спасибо!
Ответы
Ответ 1
Когда вы написали:
WithUnit(value = _, unit = "cm")
Вы хотели, чтобы это означало:
x => WithUnit(value = x, unit = "cm")
Но если вы внимательно посмотрите на сообщение об ошибке, вы увидите, что компилятор не видел этого, он проанализировал его как:
WithUnit(x => value = x, unit = "cm"})
Как вы можете видеть, объект _ больше привязан, чем вы хотели.
_ всегда выбирает самый жесткий невырожденный объем, который он может. Объем определяется чисто синтаксически, во время разбора, независимо от типов.
Невырожденным я имею в виду, что компилятор не думал, что вы имели в виду:
WithUnit(value = x => x, unit = "cm")
Самый строгий невырожденный объем означает область, определяемую самой внутренней функциональной скобкой относительно подчеркивания. Без такого правила компилятор не смог бы знать, что _ соответствует какой функции, когда вызовы функций вложены.
Ответ 2
Попробуйте следующее:
scala> val withUnits = s map { x => WithUnit(value = x, unit = "cm") }
withUnits: Seq[WithUnit] = List(WithUnit(1.0,cm), WithUnit(2.0,cm), WithUnit(3.0,cm), WithUnit(4.0,cm))
Проблема заключается в использовании подчеркивания для прямого определения любой функции.
Подробное описание находится в главе 8.5. Синтаксис заполнителя в книге "Программирование в Scala" .