即使在阅读Jatin的回答后,有些事情让我感到困惑。这是我进一步研究后的发现。请注意,为了节省输入,我不在左侧使用类型归属,并让Scala来推断。
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"
这给函数签名字符串=>(字符串,字符串)
为了解决这个问题,我们使用的第二个规则索布拉尔的答案和限制)由包围所述f1
表达(绑定到_
匿名函数或{},像下面的范围:
val r3 = (f1(_:String, "something")) -> "foo"
r3: (String => String, String) = (<function1>,foo)
现在,我们得到相同的结果作为val r1 = f2 -> "foo"
谢谢。现在对我来说很有意义。 – limuhob