Scala Elvis operator

Scala nemá Elvis operátor ?:
jako Groovy, budoucí Java 8 nebo C#, protože se místo kontrol, jestli proměnná neobsahuje null, spoléhá na typ Option[T] a pattern matching. Avšak tento jazyk disponuje natolik flexibilní syntaxí, že není problém si podporu Elvis operátoru jednoduše dopsat.
Elvis operátor je vlastně jenom zkrácená verze ternárního operátoru. Takže x ?: "default"
je stejné jako x != null ? x : "default"
.
Ve Scale se však nemůže jmenovat ?:
, protože operátory, končící dvojtečkou, se ve volají v opačném pořadí. Tedy a ?: b
by se vyhodnotilo jako b.?:(a)
(resp. { val x = a; b.?:(x) }
viz sekce 5.8 Programming in Scala).
// implementace class Elvis[T](private val v: T) { def ?(arg: T): T = if (v == null) arg else v } implicit def convertToElvis[T](x: T) = new Elvis(x) // test var x: List[String] = List("a", "b", "c") x ? List("Null") // vrátí List(a, b, c) x = null x ? List("Null") // vrátí List(Null)
Další věc, která je přítomná v Groovy a bude v Javě 8 je operátor ?.
, který slouží pro bezpečné volání metod objektu. Při použití operátoru ?. nikdy nevznikne výjimka NullPointerException, místo níž se vrátí null. Tedy x?.method()
je stejné jako x != null ? x.method() : null
.
A i tohle se dá ve Scale jednoduše implementovat. Pochopitelně není možné použít syntaxi x?.method()
, místo toho se musíme spokojit s ?(x.method())
.
// implementace def ?[T](op: => T): T = try { op } catch { case e: NullPointerException => null.asInstanceOf[T] } // test class Test { def get = "test" } var t = new Test ?(t.get) // všechno v pořádku, metoda vrátí "test" t = null ?(t.get) // nevyhodí `NullPointerException`, místo toho vrátí null ?(t.get) ?: "none" // kombinace obojího