Основные Scala Ошибки, которые не имеют смысла

Я пытаюсь получить функцию для компиляции/работы в scala и получить несколько абсолютно ошибочных сообщений об ошибках, о которых я просто не могу понять. Если я напишу свой код следующим образом:

def checkUniqueReviewNumber(number: String): Boolean = {
    val qc = new QualityClient
    if(review.isEmpty)
      false
    else {
      val qrList = qc.listInPL(Vars.currentPLId.get.get,null,null,null,null,null,null,false,false,CurrentUser.getUser.key).qualityReviews
      !qrList.exists(qr:QualityReview => qr.reviewNumber == number)
    }
  }

Я получаю сообщение об ошибке:

.../QualityReviewCreate.scala:189: error: not found: type ==
   [scalac]       !qrList.exists(qr:QualityReview => qr.reviewNumber == number)

И если я напишу код более как это:

def checkUniqueReviewNumber(number: String): Boolean = {
    val qc = new QualityClient
    if(review.isEmpty)
      false
    else {
      val qrList = qc.listInPL(Vars.currentPLId.get.get,null,null,null,null,null,null,false,false,CurrentUser.getUser.key).qualityReviews
      !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number))
    }
  }

Я получаю ошибки:

... /QualityReviewCreate.scala:189: error: ')' expected but '(' found.
   [scalac]       !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number))
   [scalac]                                                                ^
    ... /QualityReviewCreate.scala:189: error: ';' expected but ')' found.
   [scalac]       !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number))
   [scalac]                                                                        ^
   [scalac] two errors found

Здесь могут быть задействованы типы, но если это так, я совершенно не понимаю, почему. qrList должен быть java ArrayList of QualityReview, который представляет собой объект java с полем строки java, называемым reviewNumber.

Кто-нибудь понимает, что происходит здесь?

Ответ 1

Проблема состоит в том, что синтаксический анализ Scala для анонимных функций с явными типами аргументов неоднозначен, и иногда это приводит к некоторым очень странным причудам. Это одна из них. Возьмем следующее выражение:

(qr:QualityReview => qr.reviewNumber == number)

Scala (по-видимому) анализирует это следующим образом:

(qr:(QualityReview => qr.reviewNumber == number))

Это не то, что вы хотели. На самом деле это даже не анонимная функция. Дезаурирование выражения дает следующее:

(qr: Function1[QualityReview, ==[qr.reviewNumber, number]])

Итак, мы приписываем тип qr, где этот тип задается параметром Function1 с параметром QualityReview и типом, заданным параметром ==, параметризованным типами qr.reviewNumber и number. Все это действительно Scala, и я подозреваю, что ничто из этого не предназначено.

Ошибка возникает, когда Scala ищет тип с именем ==, который, конечно, он не находит (он может существовать, но это не так). Если бы эта ошибка прошла, она бы быстро столкнулась с проблемами поиска типов qr.reviewNumber и number.

Есть несколько способов избежать этой проблемы. В общем, я просто рекомендую использовать несколько иной стиль при объявлении ваших функций. Scala Руководство по стилю - это хорошее место для начала. В случае этой функции наиболее простым способом устранения проблемы является удаление аннотации типа (QualityReview). Вы также можете решить проблему, поставив круглые скобки вокруг qr:QualityReview. Кроме того, я думаю, что пробел после двоеточия может решить проблему, хотя я не могу быть уверен. Наконец, использование фигурных скобок, а не круглых скобок, обычно делает компилятор предпочтительным интерпретировать => как разделитель лямбда, а не тип. Я бы написал ваше выражение exists следующим образом:

!(qrList exists { qr => qr.reviewNumber == number })

Собственно, я, вероятно, использовал бы синтаксис подчеркивания, но это совершенно другой вопрос.: -)

!(qrList exists { _.reviewNumber == number })

Ответ 2

вам просто нужно добавить круглые скобки вокруг списка параметров; то есть.,

!qrList.exists((qr:QualityReview) => qr.reviewNumber == number)

то же самое относится ко второй попытке с .equals

вот хорошее изложение функции сахара http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html#funcdef