为什么在使用此 lambda shorthand 时编译器 select 不能使用正确的 String.contains 方法?
Why can't the compiler select the correct String.contains method when using this lambda shorthand?
假设我想检查一个字符串是否包含 any "cory":
中的字母def hasCory(input: String): Boolean = {
val myName = "cory"
input.exists(myName.contains)
}
编译器抱怨:
error: type mismatch;
found : CharSequence => Boolean
required: Char => Boolean
Scala 提供了我想要的Char
-接受方法in StringOps:
但是编译器似乎看不到这个方法,除非我将代码更改为以下之一:
input.exists(myName.contains(_))
input.exists(c => myName.contains(c))
在原来的例子中,它似乎使用了 Java String's contains
method,这确实 接受 CharSequence
:
这是否按预期工作?为什么编译器看不到我想要 contains
的 Char
版本?
StringOps
是 an implicit conversion
@inline implicit def augmentString(x: String): StringOps = new StringOps(x)
并且隐式转换仅适用于in three cases:
- If an expression is of type , and does not conform to the expression's expected type pt.
- In a selection . with of type , if the selector does not denote an accessible member of .
- In a selection .(args) with of type , if the selector denotes some member(s) of , but none of these members is applicable to the arguments args.
当你写 myName.contains
时,它是三种情况中的 none(特别是,
不是第二种情况,因为 contains
是 String
) 的可访问成员,所以 StringOps
不能应用,它是 String#contains(CharSequence)
和类型不匹配错误。
当你写myName.contains(_)
或c => myName.contains(c)
时是第3种情况所以StringOps
可以应用并且隐式转换后是StringOps#contains(Char)
是的,它按预期工作。