Почему компилятор не может выбрать правильный метод String.contains при использовании этого сокращения лямбда? - PullRequest
0 голосов
/ 06 августа 2020

Допустим, я хочу проверить, содержит ли строка любые букв в «cory»:

def hasCory(input: String): Boolean = {
  val myName = "cory"
  input.exists(myName.contains)
}

Компилятор жалуется на:

error: type mismatch;
found   : CharSequence => Boolean
required: Char => Boolean

Scala предоставляет Char -принимающий метод, который я хочу в StringOps :

scaladoc showing the contains method signature

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 contains метод , который действительно принимает CharSequence:

документация по методу Java String.contains

Это работает как задумано? Почему компилятор не видит, что мне нужна Char версия contains?

1 Ответ

4 голосов
/ 07 августа 2020

StringOps - неявное преобразование

@inline implicit def augmentString(x: String): StringOps = new StringOps(x)

И неявное преобразование применимо только в трех случаях только:

  1. Если выражение ? относится к типу ?, а ? не соответствует ожидаемому типу выражения pt.
  2. В выделении ?.? с ? типа ?, если селектор ? соответствует не обозначает доступный член ? .
  3. В выделении ?.? (args) с ? типа ?, если селектор ? обозначает некоторый член (ы), но ни один из этих членов применимо к аргументам args.

Когда вы пишете myName.contains, это ни один из трех случаев (в частности, не второй случай, потому что contains является доступным членом String), поэтому StringOps не может быть применен, и это String#contains(CharSequence) и ошибка несоответствия типа.

Когда вы напишите myName.contains(_) или c => myName.contains(c), это 3-й случай, поэтому можно применить StringOps, и это StringOps#contains(Char) после неявного преобразования.

Так что да, он работает как задумано.

...