k47.cz  — každý den dokud se vám to nezačne líbit
výběr foto Praha povídky kultura
TECH ▞▞ kolo | twitter RSS

Scala Elvis operator

25. 11. 2010 (před 8 lety) — k47 (CC by-sa) (♪)

Scala nemá Elvis ope­rá­tor ?: jako Groovy, bu­doucí Java 8 nebo C#, pro­tože se místo kon­t­rol, jestli pro­měnná ne­ob­sa­huje null, spo­léhá na typ Option[T] a pat­tern matching. Avšak tento jazyk dis­po­nuje na­to­lik fle­xi­bilní syn­taxí, že není pro­blém si pod­poru Elvis ope­rá­toru jed­no­duše dopsat.


Elvis ope­rá­tor je vlastně jenom zkrá­cená verze ter­nár­ního ope­rá­toru. Takže x ?: "default" je stejné jako x != null ? x : "default".

Ve Scale se však nemůže jme­no­vat ?:, pro­tože ope­rá­tory, kon­čící dvoj­teč­kou, se ve volají v opač­ném pořadí. Tedy a ?: b by se vy­hod­no­tilo jako b.?:(a) (resp. { val x = a; b.?:(x) } viz sekce 5.8 Pro­gra­m­ming 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 ope­rá­tor ?., který slouží pro bez­pečné volání metod ob­jektu. Při po­u­žití ope­rá­toru ?. nikdy ne­vznikne vý­jimka Null­Poin­te­rEx­cep­tion, 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 jed­no­duše im­ple­men­to­vat. Po­cho­pi­telně není možné použít syn­taxi x?.method(), místo toho se musíme spo­ko­jit 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
píše k47 & hosté, ascii@k47.cz