Я продолжаю возвращаться к удивительному вводному материалу по Scala, составленному Дэниелом Вестхайде . Одним из примеров, которые он предоставляет для экстракторов, использующих шаблон операции инфикса, является Streams API —
1
2
3
4
5
|
val xs = 58 #:: 43 #:: 93 #:: Stream.empty xs match { case first #:: second #:: _ => first - second case _ => - 1 } |
где экстрактор определяется следующим образом:
1
2
3
4
5
|
object #:: { def unapply[A](xs: Stream[A]): Option[(A, Stream[A])] = if (xs.isEmpty) None else Some((xs.head, xs.tail)) } |
Учитывая это, я хотел попробовать экстрактор на выборках Rational Number из книги Scala by Example , вот как выглядит Rational number:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
class Rational(n: Int, d: Int) { private def gcd(x: Int, y: Int): Int = { if (x == 0 ) y else if (x < 0 ) gcd(-x,y) else if (y < 0 ) -gcd(x, -y) else gcd(y % x, x) } private val g = gcd(n, d) val numer: Int = n/g val denom: Int = d/g def +(that: Rational) = new Rational(numer * that.denom + that.numer * denom, denom * that.denom) def -(that: Rational) = new Rational(numer * that.denom - that.numer * denom, denom * that.denom) def *(that: Rational) = new Rational(numer * that.numer, denom * that.denom) def /(that: Rational) = new Rational(numer * that.denom, denom * that.numer) override def toString = "" + numer + "/" + denom + "" def square = new Rational(numer*numer, denom*denom) } |
и я хотел экстрактор, который будет вести себя следующим образом:
1
2
3
4
5
|
val r = new Rational( 2 , 3 ) r match { case num / denom => num + "/" + denom } |
Это абсолютно выполнимо в Scala, учитывая гибкость в именах идентификаторов. Учитывая это, экстрактор с именем «/» может быть определен следующим образом:
1
2
3
|
object / { def unapply(r: Rational): Option[(Int, Int)] = Some(r.numer, r.denom) } |
и используется для извлечения числителя и знаменателя рационального числа!
1
2
3
4
5
6
7
8
|
r match { case /(num, denom) => num + "/" + denom } //using infix r match { case num / denom => num + "/" + denom } |
Ссылка: | Scala экстракторы инкапсулируют образец с номерами Rational от нашего партнера JCG Биджу Кунджуммен в блоге all and sundry. |