2013-07-21 3 views
4

Интересно, почему это не работает:соответствие шаблону не работает

def example(list: List[Int]) = list match { 
    case Nil => println("Nil") 
    case List(x) => println(x) 
    }            

    example(List(11, 3, -5, 5, 889, 955, 1024)) 

Он говорит:

scala.MatchError: List(11, 3, -5, 5, 889, 955, 1024) (of class scala.collection.immutable.$colon$colon) 

ответ

15

Это не работает, потому что List(x) означает список только с одним элементом. Проверьте это:

def example(list: List[Int]) = list match { 
    case Nil => println("Nil") 
    case List(x) => println("one element: " + x) 
    case xs => println("more elements: " + xs) 
} 

example(List(11, 3, -5, 5, 889, 955, 1024)) 
//more elements: List(11, 3, -5, 5, 889, 955, 1024) 
example(List(5)) 
//one element: 5 
+0

хз может быть любого типа. как я могу уловить xs типа List [Int] точно? –

+2

Это обычная проблема в scala, полезная ссылка: http://stackoverflow.com/questions/12218641/scala-2-10-what-is-a-typetag-and-how-do-i-use-it – Infinity

6

Поскольку List(x) соответствует только списки с одним элементом. Таким образом,

def example(list: List[Int]) = list match { 
    case Nil => println("Nil") 
    case List(x) => println(x) 
} 

работает только со списками нулевого или одного элемента.

2

Как и другие плакаты уже указывали, List(x) соответствует только список 1 элемента.

Существует, однако синтаксис для сопоставления нескольких элементов:

def example(list: List[Int]) = list match { 
    case Nil => println("Nil") 
    case List(x @ _*) => println(x) 
}            

example(List(11, 3, -5, 5, 889, 955, 1024)) // Prints List(11, 3, -5, 5, 889, 955, 1024) 

Это смешно @ _*, что делает разницу. _* соответствует повторному параметру, а x @ говорит: «Свяжите это с x».

То же самое работает с любым совпадением шаблонов, которое может соответствовать повторяющимся элементам (например, Array(x @ _*) или Seq(x @ _*)). List(x @ _*) также может соответствовать пустым спискам, хотя в этом случае мы уже сопоставили Nil.

Вы также можете использовать _*, чтобы соответствовать «остальные», как в:

def example(list: List[Int]) = list match { 
    case Nil => println("Nil") 
    case List(x) => println(x) 
    case List(x, xs @ _*) => println(x + " and then " + xs) 
} 
+0

как насчет (x :: xs)? –

+0

@Grienders Не могли бы вы рассказать? Что бы вы хотели узнать о (x :: xs)? –

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