Некоторые вещи меня смущали даже после прочтения ответа Джатина. Вот мои выводы после некоторых дальнейших исследований. Обратите внимание: чтобы сохранить ввод текста, я не использую титры с левой стороны и пусть материал Scala infer.
def f1(n: String, m: String): String = m + n
// f1: (n: String, m: String)String
val f2 = f1(_, "something")
Как правило, подчеркивания в выражении представляют собой анонимные функции, которые соответствующим образом расширяются компилятором. Если компилятор не может найти подходящий тип для «подчеркивания» параметра, он будет жаловаться, как показано ниже:
// <console>:12: error: missing parameter type for expanded function ((x$1) => f1(x$1, "something"))
val f2 = f1(_:String, "something") // Specifiying the type of the `_` as `_:String` fixes the missing parameter type error above.
// f2: String => String = <function1>
val r1 = f2 -> "foo"
// r1: (String => String, String) = (<function1>,foo)
Теперь важные вещи. Почему нижняя строка не дает тот же результат, что и r1 выше! Причина кроется в отличном ответе Даниилом в underscore scoping rules.
val r2 = f1(_:String, "something") -> "foo"
// r2: String => (String, String) = <function1>
В соответствии с 1-го правила в ответ Даниилом, объем анонимной функции будет включать в себя всю правую часть выражения в . Так расширенная анонимная функция выше будет
(x:String) => f1(x:String, "something") -> "foo"
Что дает функцию подписи: String => (String, String)
Для того, чтобы исправить это, мы используем 2-ое правило в ответ Собрал и ограничить объем анонимной функции, связанной с _
, заключив f1
выражение с() или {}, как показано ниже:
val r3 = (f1(_:String, "something")) -> "foo"
r3: (String => String, String) = (<function1>,foo)
Теперь, мы получаем тот же результат, как val r1 = f2 -> "foo"
Спасибо. Теперь это имеет смысл. – limuhob