2014-10-12 4 views
0

Я только начал изучать Скала, и я заметил, что : используется во многих местах. В большинстве случаев использование : имеет смысл, например. после имен параметров или деклараций метода. Следующее использование меня смущает, однако:Что означает: означает значение после Scala?

val a = Seq[String]("a", "b") 
a :+ "c" 

или

def myMethod(varargs: String*) { 
    // ... 
} 
val a = Seq[String]("a", "b", "c") 
myMethod(a:_*) 

Что именно это : делать в этих случаях? Почему я не могу позвонить a._* напрямую?

ответ

4

Два обычаи, о которых вы спрашиваете, это два совершенно разных случая.

a :+ "c" 

: ничего не значит здесь; это часть метода с именем :+, который добавляет элемент в Seq.

myMethod(a:_*) 

Здесь у вас есть метод myMethod который принимает переменное число аргументов. Вы хотите использовать Seq для заполнения аргументов; : _* указывает, что вы хотите сделать это (вместо того, чтобы передавать Seq в качестве первого аргумента метода).

Обратите внимание, что : имеет особое значение, если имя метода заканчивается с : (не, если она начинается с :, как в первом примере). В этом случае метод будет право-ассоциативный; это означает, что метод будет вызван на предмет справа, а вещь слева как аргумент, а не наоборот.

+0

Спасибо. Как это говорит: _ * *? Если бы я хотел сам реализовать эту функциональность, как бы мне это сделать? – Max

+1

+1 Заметим, что любой метод, заканчивающийся на '+', является право-ассоциативным. –

+0

@Max Посмотрите на [Daily Scala: Varargs] (http://daily-scala.blogspot.nl/2009/11/varargs.html), чтобы узнать, как сделать свой собственный метод, который принимает переменное количество аргументов. – Jesper

0

:+ - это метод на Seq[A], который добавляет данный элемент в последовательность.

Во втором примере myMethod(a : _*)a : _* используется для передачи последовательности в качестве списка аргументов переменных в функцию myMethod.

2

Сообщает компилятору, что вы хотите, чтобы ваша последовательность была разобрана и предоставлена ​​в виде отдельных параметров.

def myMethod(varargs: String*) = { 
    // varargs is a Seq 
    val x:Seq[String] = varargs 
} 

// Calling it is different 
myMethod("a", "b") 

// To call using a seq, you need to signal the compiler 
myMethod(mySeqOfString: _*) 

// They choose the `:` because this would be valid too: 
myMethod(myString: String) 

Int другого примера вы дали a :+ "c": имеют другое значение. Это просто часть имени метода. Они могли назвать его append, но они выбрали :+. Причина в том, что : в +: имеет специальное значение: bind to the right. Это позволяет использовать "c" +: a. Поэтому для согласованности они, вероятно, выбрали :+ для append и +: для preend.

+0

+1 Заметим, что любой метод, заканчивающийся на '+', является правильным ассоциативным. –

0

Значение толстой кишки в Скале варьируется в зависимости от контекста.

Как вы заметили, он отделяет идентификатор в объявлении от его типа.

Он может также отображаться как часть оператора, включающего последовательность.

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

Так что ваш пример

a :+ "c" 

Добавляет строку "c" в a последовательность строк, в то время как

"c" +: a 

Вставляет строку в последовательности. (Или, точнее, в случае неизменной последовательности, возвращают новую последовательность, полученную из препенда/добавить операцию. См documentation)

Вашего последний пример

myMethod(a: _*) 

(который я должен был искать спасибо за обучение! см. documentation) сообщает компилятору развернуть последовательность как varargs (а не как один аргумент).

+0

Вы должны, вероятно, упомянуть ассоциативность quirk '+:', для полноты. – acjay

+0

Следует отметить, что '+:' является эквивалентом Seq списка '::' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' –

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