Dopasowanie do wzorca pobiera dane wejściowe i rozkłada je za pomocą funkcji unapply
. Tak więc w twoim przypadku unapply(4)
musiałby zwrócić dwie liczby, które sumują się do 4. Istnieje jednak wiele par, które sumują się do 4, więc funkcja nie wie, co zrobić.
W razie potrzeby funkcja 2
jest dostępna dla funkcji unapply
. Specjalna klasa sprawa, która przechowuje 2
będzie działać na to:
case class Sum(addto: Int) {
def unapply(i: Int) = Some(i - addto)
}
val Sum2 = Sum(2)
val Sum2(x) = 5 // x = 3
(Byłoby miło być w stanie coś zrobić jak val Sum(2)(y) = 5
dla zwięzłości, ale Scala nie pozwala parametryzowane extractory patrz here.)
[EDIT: to jest trochę głupie, ale może faktycznie zrobić następujące też:
val `2 +` = Sum(2)
val `2 +`(y) = 5 // y = 3
]
EDIT: Powodem, dla którego działa head::tail
jest to, że istnieje dokładnie jeden sposób na rozdzielenie głowy od końca listy.
Nic z natury specjalnego ::
kontra +
: można użyć +
jeśli miał ustaloną pomysł jak chciał go złamać numer. Na przykład, jeśli chcesz +
oznacza „podzielone na pół”, a następnie można zrobić coś takiego:
object + {
def unapply(i: Int) = Some(i-i/2, i/2)
}
i używać go jak:
scala> val a + b = 4
a: Int = 2
b: Int = 2
scala> val c + d = 5
c: Int = 3
d: Int = 2
EDIT: Wreszcie this wyjaśnia, że kiedy Dopasowywanie wzorców, A op B
oznacza to samo co op(A,B)
, co sprawia, że składnia wygląda ładnie.
Dlaczego nie używasz 'y-2' (gdy y = 4)? –
To jest bardziej ciekawostka, więc nie mam konkretnych przykładów, ale wyobrażałem sobie, że jest to miłe dla bardziej złożonych klas. – Dylan