2014-10-13 1 views
1

Какая объяснительная марка делает в (!_._2.isEmpty)?Значение восклицательного знака в zipAll .takeWhile (! _._ 2.isEmpty)

Как и в:

def startsWith[A](s: Stream[A]): Boolean = 
    zipAll(s).takeWhile(!_._2.isEmpty) forAll { 
     case (h,h2) => h == h2 
    } 

взяты из Stream.

Это просто отрицание?

Если да, то почему не нужно пространство между ! и _?

Не является !_ интерпретирован как метод name?

Могут ли имена методов содержать или начинаться с !?

+3

'! _' так же, как'! X', за что '_' средства, за исключением. То есть, как 'x', так и' _' являются действительным (полным-в-контексте) идентификатором, а Scala (лучше или хуже) здесь не является чувствительным к пробелу. Во всем контексте он эквивалентен форме с явной скобкой - '! (((_) ._ 2) .isEmpty)'. Overkill, но он должен показать разбор синтаксического разбора. – user2864740

+0

(Правила lex'ing в «white-space/identifier» также объясняют, почему нужно использовать 'foo_ =', а не 'foo =', последний из которых анализируется как 'foo',' = '. И * all * этого описан в [Спецификации языка Scala] (http://www.scala-lang.org/documentation/). – user2864740

+0

Спасибо за объяснение! – jhegedus

ответ

1

Это просто отрицание. расширение определения путем замены _ более подробным именем может сделать это более очевидным.

def startsWith[A](s: Stream[A]): Boolean = 
zipAll(s).takeWhile(!_._2.isEmpty) forAll { 
    case (h,h2) => h == h2 
} 

можно переписать в виде

def startsWith[A](s: Stream[A]): Boolean = 
zipAll(s).takeWhile(element => !element._2.isEmpty) forAll { 
    case (h,h2) => h == h2 
} 

._2 это только второй элемент в кортеж, в данном случае, похоже, этот список является пара пунктов (ссылки позже ч и h2) так что вы могли бы также переписать по распаковке элементов в паре значений как

def startsWith[A](s: Stream[A]): Boolean = 
zipAll(s).takeWhile{ element => 
    val (h, h2) = element 
    !h2.isEmpty 
} forAll { 
    case (h,h2) => h == h2 
} 
0

Является ли это просто отрицание?

Да

Если да, то почему нет места требуется между ними! а также _ ?

Поскольку грамматика позволяет

Не! _ Интерпретируется как имя метода?

Нет, потому что . связывает сильнее, чем !, поэтому выражение обрабатывается как !(_._2.isEmpty)

Кроме того, !_ даже не является допустимым именем метода (опять-таки, указанный в грамматике, смотри ниже)

Могут ли имена методов содержать или начинаться с !?

Да, но не свободно. Ниже приведены правила для именования идентификаторов, прямо из спецификации языка:

Существует три способа формирования идентификатора. Во-первых, идентификатор может начинаться с буквы , за которой может следовать произвольная последовательность букв и цифр.Это может быть , за которым следует символ подчеркивания ' _ ' и другая строка, состоящая либо из букв , либо цифр или символов оператора. Во-вторых, идентификатор может начинаться с символа оператора , за которым следует произвольная последовательность символов оператора. Предыдущие две формы называются равными идентификаторами. Наконец, идентификатор также может быть сформирован произвольной строкой между обратными кавычками (хост-системы могут налагать некоторые ограничения , по которым строки являются юридическими для идентификаторов). Идентификатор затем состоит из всех символов, исключая сами обратные кавычки. Как обычно, применяется самое длинное правило соответствия.

(The Scala Language Specification, Version 2.9, Chapter 1.1)

Смежные вопросы