k47.cz
výběr kolo foto makro povídky kultura
koronavirus TECH ▞▞ | twitter RSS

Scala - postfixový if

8. 12. 2010 (aktualizováno 30. 5. 2021) — k47 (CC by-sa)

Ně­které jazyky jako třeba Ruby, Python nebo třeba Co­f­fe­Script mají tak­zvaný po­st­fi­xový if a jeho obdobu unless, tedy pod­mínku, která se za­pi­suje ve for­mátu doSomething() if condition. Tahle syn­taxe může být o něco pří­jem­nější, pro­tože je bližší při­ro­ze­nému jazyku.

Scala po­st­fi­xový if nemá, ale – há­dejte co – je to jazyk na­to­lik fle­xi­bilní, že v něm není pro­blém im­ple­men­to­vat vše, po čem vaše srdce touží. Bo­hu­žel ne­mů­žeme použít klí­čové slovo if, což je jediná vada na kráse. Tedy takhle: můžeme použít if, ale musíme ho pak vždy uvádět ve zpět­ných apo­stro­fech. Svému účelu po­slouží ozna­čení iff.

class Iff[T](a: => T) {
  def iff(cond: => Boolean) = if (cond) Some(a) else None
  def unless(cond: => Boolean) = if (cond) None else Some(a)
}

import scala.language.implicitConversions

implicit def postfixIf[T](a: => T): Iff[T] = new Iff(a)

// test
println("Je tam ještě?") iff true        // vypíše text
println("Je tam ještě?") iff 1 == 0      // nevypíše nic

println("Je tam ještě?") unless false    // vypíše text
println("Je tam ještě?") unless 1 == 1   // nevypíše nic

Vše fun­guje díky im­pli­cit­ním kon­ver­zím a ar­gu­men­tům pře­dá­va­ným jménem. Pod­mí­něný kód se pro­vede sku­tečně jen tehdy, když je pod­mínka prav­divá.


Výše uve­dený kód stále fun­guje ve Scale 3. Ta nicméně nabízí pro­středky jak vy­já­d­řit to samé přímo bez im­pli­cit­ních kon­verzí a po­moc­ných tříd. Třetí verze jazyka uvedla klí­čové slovo ex­tension, které do­vo­luje přidat metody k již exis­tu­jí­címu typu. Vý­sle­dek má iden­tic­kou funk­ci­o­na­litu, jen přímo říká, že metody roz­ši­řují ge­ne­rický typ T.

extension[T] (x: => T) {
  infix def iff(cond: Boolean) = if (cond) Some(x) else None
  infix def unless(cond: Boolean) = if (cond) Some(x) else None
}

Klí­čové slovo infix po­vo­luje, aby se iffunless mohly volat jako ope­rá­tory syn­taxí a iff b, na­místo pouze a.iff(b).

píše k47 & hosté, ascii@k47.cz