Разница между func (_) и func _ - PullRequest
4 голосов
/ 21 февраля 2011

Кто-нибудь может сказать мне разницу между func _ и func (_) в Scala? Мне пришлось переопределить этот метод:

def validations: List[ValueType => List[FieldError]] = Nil

Если я переопределю это с помощью:

val email = new EmailField(this, 255){
  override def validations = valUnique _ :: Nil
  private def valUnique(email: String): List[FieldError] = {
    Nil
  }
}

Это нормально, если я переопределю это с помощью:

val email = new EmailField(this, 255){
  override def validations = valUnique(_) :: Nil
  private def valUnique(email: String): List[FieldError] = {
    Nil
  }
}

Это не хорошо. Кто-нибудь может мне объяснить, почему? Большое спасибо.

Ответы [ 2 ]

8 голосов
/ 21 февраля 2011

В случае:

valUnique _

Вы частично применяете метод valUnique, вызывая его упаковку в виде функции.

С другой стороны:

valUnique(_)

указывает местозаполнитель для вызова метода valUnique, что обычно делается для передачи анонимной функции какой-либо другой функции высокого порядка, например:

emails flatMap { valUnique(_) }

В вашем случае в области действия нет ничего, что можно было бы использовать для выполнения такого заполнителя, хотя частичное применение все еще полностью допустимо.

Обратите внимание, что вы также можете поднять метод до функции перед передачей его в качестве аргумента:

emails flatMap { valUnique _ }

Это сходство почти наверняка является причиной вашего замешательства, хотя эти две формы не делают совсем то же самое за кадром.

4 голосов
/ 21 февраля 2011

Если бы вы написали это так:

override def validations: List[ValueType => List[FieldError]] = valUnique(_) :: Nil

Я уверен, это скажет вам, что вы получаете String => List[List[FieldError]] вместо требуемого типа.Когда подчеркивание используется вместо параметра (а не как часть выражения), оно раскрывается как функция в непосредственной внешней области видимости.В частности,

valUnique(_) :: Nil  // is translated into
x => valUnique(x) :: Nil

(valUnique(_)) :: Nil  // would be translated into
(x => valUnique(x)) :: Nil  // which would be correct

С другой стороны, valUnique _ просто говорит «получить этот метод и превратить его в функцию», поэтому

valUnique _ :: Nil  // gets translated into
(x => valUnique(x)) :: Nil
...