24.3. Wyrażenie either/or
W pliku EitherOr.scala zdefiniowany jest obiekt select, który pozwala na zastosowanie w programie konstrukcji składającej się ze słów either oraz or, pozwalającej na losowe wykonanie jednego z dwóch zdefiniowanych fragmentów kodu.
Plik EitherOr.scala: import scala.util.Random object select { def either[A](a: => A) = new { def or[B >: A](b: => B) = if (Random.nextBoolean) a else b } }
Poniższy przykład ilustruje sposób wykorzystania tej konstrukcji.
scala> import language.reflectiveCalls import language.reflectiveCalls scala> select either "Hi" or "Hello" res1: String = Hi scala> select either "Hi" or "Hello" res2: String = Hello scala> select either Some(1) or None res3: Option[Int] = None scala> select either Some(1) or None res4: Option[Int] = Some(1)
Metoda either ma jeden parametr i zwraca obiekt implementujący anonimową klasę, w której zdefiniowana jest metoda or. Metoda or, podobnie jak either, ma jeden parametr. W metodzie or wywoływana jest metoda Random.nextBoolean i w zależności od zwróconego przez nią rezultatu, metoda or zwraca rezultat ewaluacji argumentu metody either albo argumentu metody or. Wykorzystanie parametrów typu oraz ograniczenia dolnego powoduje, że typem całego wyrażenia jest wspólny nadtyp wyrażeń przekazanych metodom either i or. W przypadku wyrażeń z wierszy i jest to String, a w przypadku wyrażeń z wierszy i jest to Option[Int]. W powyższych wyrażeniach wykorzystana została notacja infiksowa, dzięki czemu nie trzeba było otaczać argumentów metod either i or nawiasami. Nazwa obiektu select została specjalnie dobrana w taki sposób, aby pasowała do słów either i or. Import z wiersza jest użyty w celu uniknięcia ostrzeżenia kompilacji.