2016-03-01 5 views
1

В примере ниже есть функция seqResult, которая соответствует шаблону Seq. Другая функция, которая принимает переменные аргументы, вызывает seqResult и передает в ArrayBuffer. Это приводит к тому, что результат совпадения шаблонов будет отличаться при вызове с Seq или с ArrayBuffer.pattern match возвращает другой результат для ArrayBuffer и Seq

С Seq совпадения хитов case head :: rest => ..., с ArrayBuffer совпадения хитов case Seq(one, two) => ....

Это ошибка? Есть ли способ защититься от этого?

Если это не ошибка, то какой безопасный способ соответствовать списку из 1 или более записей, которые будут работать для Seq(a,b) и ArrayBuffer(a,b)?

def seqResult(arr:Seq[String]) = arr match { 
    case Nil => "Nil" 
    case head :: Nil => "head :: Nil" 
    case head :: rest => "head :: rest" 
    case Seq(one, two) => "one, two" 
    case _ => "other" 
} 

def varArgResult(args:String*) = seqResult(args) 

val ab = varArgResult("one", "two") 
val se = seqResult(Seq("one", "two")) 

println(ab) //=> "one, two" 
println(se) //=> "head :: rest" 

ответ

1

:: является экстракторным объектом для List. Поскольку списки являются реализацией по умолчанию Seq, это то, что вы видите, когда используете Seq(a, b, ...).

Экстрактор для Seq s is +:.

+0

Приветствия - что я искал –

1

args: String* фактически Array

Seq() конструктор использует конструктор, основанный на ListBuffer так как результат мы имеем List типа данных.

object Seq extends SeqFactory[Seq] { 
    def newBuilder[A]: Builder[A, Seq[A]] = new mutable.ListBuffer 
} 

...

println(Seq("one", "two")) 

List(one, two) 

head::rest является синтаксисом для List согласования и может быть представлен в виде List(head, rest) что матч se в вашем случае.

+0

только что добавил последний вопрос - какой вариант наилучшего соответствия в этом случае? –

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

  • Нет связанных вопросов^_^