Почему существует разница в поведении между этими двумя совпадениями шаблонов для понимания? - PullRequest
4 голосов
/ 10 февраля 2011

Рассмотрим это Map[String, Any]:

val m1 = Map(("k1" -> "v1"), ("k2" -> 10))

Теперь давайте напишем for:

scala> for ((a, b) <- m1) println(a + b)
k1v1
k210

Пока все хорошо.

Теперь давайте определим тип второго члена:

scala> for ((a, b: String) <- m1) println(a + b)
k1v1

scala> for ((a, b: Integer) <- m1) println(a + b)
k210

Здесь, когда я указываю тип, происходит фильтрация, и это здорово.

Теперь скажите, что вместо этого я хочу использовать массив [Любой]:

val l1 = Array("a", 2)

Здесь вещи ломаются:

scala> for (v: String <- l1) println(v)
<console>:7: error: type mismatch;
 found   : (String) => Unit
 required: (Any) => ?

Мой двойной вопрос:

  • почему второй фильтр совпадений также не фильтруется?
  • есть ли способ выразить такую ​​фильтрацию во втором сценарии без использования грязного isInstanceOf?

Ответы [ 2 ]

12 голосов
/ 10 февраля 2011

Ну, последний пример не работает, потому что он не предназначен. Есть некоторое обсуждение относительно того, что было бы разумным поведением. Лично я ожидал бы, что это сработает так же, как и вы. Дело в том, что:

val v: String = (10: Any) // is a compile error
(10: Any) match {
    case v: String =>
} // throws an exception

Если вы не уверены в этом, вступите в клуб . :-) Вот обходной путь:

for (va @ (v: String) <- l1) println(v)
9 голосов
/ 10 февраля 2011

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

val x: String = y       // type check, can fail at compile time
val (x: String) = y     // pattern match, can fail at run time

for (x: String <- ys)   // type check, can fail at compile time
for ((x: String) <- ys) // pattern match, can filter at run time
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...