Why can't the compiler select the correct String.contains method when using this lambda shorthand?

牧云@^-^@ 提交于 2021-01-29 14:30:00

问题


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:

  1. If an expression 𝑒 is of type 𝑇, and 𝑇 does not conform to the expression's expected type pt.
  2. In a selection 𝑒.𝑚 with 𝑒 of type 𝑇, if the selector 𝑚 does not denote an accessible member of 𝑇.
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!