问题
Say I want to check if a string contains any of the letters in "cory":
def hasCory(input: String): Boolean = {
val myName = "cory"
input.exists(myName.contains)
}
The compiler complains with:
error: type mismatch;
found : CharSequence => Boolean
required: Char => Boolean
Scala provides the Char
-accepting method I want in StringOps:
But it appears that the compiler cannot see this method unless I change the code to one of:
input.exists(myName.contains(_))
input.exists(c => myName.contains(c))
Instead in the original example it appears to be using Java String's contains method, which indeed does accept a CharSequence
:
Is this working as intended? Why can't the compiler see that I want the Char
version of contains
?
回答1:
StringOps
is an implicit conversion
@inline implicit def augmentString(x: String): StringOps = new StringOps(x)
And implicit conversion are applicable in three cases only:
- 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.
When you write myName.contains
it's none of the three cases (in particular,
not the 2nd case because contains
is an accessible member of String
) so StringOps
can't be applied and it's String#contains(CharSequence)
and type mismatch error.
When you write myName.contains(_)
or c => myName.contains(c)
it's the 3rd case so StringOps
can be applied and it's StringOps#contains(Char)
after implicit conversion.
So yes, it's working as intended.
来源:https://stackoverflow.com/questions/63291510/why-cant-the-compiler-select-the-correct-string-contains-method-when-using-this