Как скала соответствует на массивах? - PullRequest
1 голос
/ 31 октября 2011

при просмотре кода Scala удобный синтаксис создания массива достигается путем добавления метода apply к object Array. Сначала я думал, что это было как-то достигнуто с помощью классов case, потому что вы можете запустить следующее, но это не так:

Array(1,2,3) match { case Array(a, b, c) => a + b + c }

Я знаю, что мне также нужно взглянуть на WrappedArray и все суперклассы, но я не могу понять, как scala достигает этого соответствия на массивах (и мне нужно больше познакомиться с иерархией классов коллекций scala). Это, конечно, не работает с классическим классом.

scala>  class A(val x: Int)
scala>  new A(4) match { case A(x) => x }
<console>:9: error: not found: value A
              new A(4) match { case A(x) => x }
                                    ^
<console>:9: error: not found: value x
              new A(4) match { case A(x) => x }

Как они работают с Array?

1 Ответ

5 голосов
/ 31 октября 2011

Вы можете сопоставить шаблон с этим синтаксисом в любом классе, если у вас есть объект с помощью метода unapply или unapplySeq (в случае varargs), который возвращает Option или Boolean. Они известны как экстракторы . Рассматриваемые строки из объекта Array:

  def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] =
    if (x == null) None else Some(x.toIndexedSeq) 

В вашем примере вы можете получить его, используя

class A(val x: Int)

object A {
  def unapply(a: A) = Some(a.x)
}

так что теперь

scala> new A(4) match { case A(x) => x }
res1: Int = 4

Программирование в Scala глава о экстракторах может быть полезна.

Для case-классов метод unapply является лишь одним из методов, включенных бесплатно, наряду с toString, equals и т. Д.

Обратите внимание, что экстрактор не должен иметь того же имени, что и рассматриваемый класс, и его не нужно определять в объекте object. Например, в вашем случае вы могли бы одинаково написать

val xyz = new { def unapply(a: A) = Some(a.x) } //extending java.lang.Object

new A(4) match { case xyz(x) => x }             //Int = 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...