Scala för backendutveckling och funktionell programmering · Lektion

Implicita parametrar

Skicka kontext.

Lektion 1 av 413 steg

Implicita parametrar är en gratis lektion i Scala för backendutveckling och funktionell programmering på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Scala för backendutveckling och funktionell programmering, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Scala för backendutveckling och funktionell programmering innehåller totalt 4 lektioner.

Skicka kontext automatiskt

Implicit-parametrar låter kompilatorn tillhandahålla ett argument åt Er, hämtat från värden som är markerade med implicit i scopet. De passar bra för att skicka omgivande kontext, till exempel konfiguration eller formateringsregler.

object Main {
  def greet(name: String)(implicit greeting: String): String =
    s"$greeting, $name!"
  implicit val defaultGreeting: String = "Hello"
  def main(args: Array[String]): Unit = {
    println(greet("Ann"))
  }
}

Den implicita parameterlistan

Markera den sista parameterlistan med nyckelordet implicit. När Ni utelämnar den vid anropet söker kompilatorn efter ett matchande implicit värde.

object Main {
  def multiply(x: Int)(implicit factor: Int): Int = x * factor
  implicit val f: Int = 10
  def main(args: Array[String]): Unit = {
    println(multiply(5))
  }
}

Tillhandahålla implicita värden explicit

Ni kan alltid skicka en implicit parameter explicit och därmed åsidosätta den som finns i scopet. Det är praktiskt i enstaka fall.

object Main {
  def multiply(x: Int)(implicit factor: Int): Int = x * factor
  implicit val f: Int = 10
  def main(args: Array[String]): Unit = {
    println(multiply(5))
    println(multiply(5)(2))
  }
}

Implicit upplösning efter typ

Kompilatorn matchar implicita värden efter typ, inte efter namn. Det måste finnas exakt ett matchande implicit värde i scopet, annars misslyckas kompileringen på grund av tvetydighet eller ett saknat värde.

object Main {
  case class Config(env: String)
  def run()(implicit cfg: Config): String = s"running in ${cfg.env}"
  implicit val cfg: Config = Config("prod")
  def main(args: Array[String]): Unit = {
    println(run())
  }
}

implicitly för att hämta ett värde

Hjälpfunktionen implicitly[T] hämtar det implicita värdet av typen T direkt från scopet, utan att en parameter behöver namnges.

object Main {
  implicit val name: String = "Scala"
  def main(args: Array[String]): Unit = {
    val n = implicitly[String]
    println(n)
  }
}

Kortform för kontextbundenhet

En kontextbundenhet [T: Ordering] är syntaktiskt socker för en implicit parameter av typen Ordering[T]. Den används ofta med typklasser.

object Main {
  def max[T: Ordering](a: T, b: T): T = {
    val ord = implicitly[Ordering[T]]
    if (ord.gt(a, b)) a else b
  }
  def main(args: Array[String]): Unit = {
    println(max(3, 7))
    println(max("apple", "pear"))
  }
}

Föra kontext genom anrop

Implicit-parametrar är särskilt användbara när många funktioner behöver samma kontext. Markera den som implicit en gång, så förs den automatiskt vidare genom nästlade anrop.

object Main {
  case class User(name: String)
  def log(msg: String)(implicit u: User): Unit =
    println(s"[${u.name}] $msg")
  def doWork()(implicit u: User): Unit = {
    log("started")
    log("finished")
  }
  implicit val current: User = User("admin")
  def main(args: Array[String]): Unit = {
    doWork()
  }
}

Var implicita värden söks

Kompilatorn söker efter implicita värden i det lokala scopet, bland importer och i companion objects för de berörda typerna. Companion objects är en tydlig plats för standardvärden.

object Main {
  case class Currency(symbol: String)
  object Currency {
    implicit val default: Currency = Currency("$")
  }
  def price(amount: Int)(implicit c: Currency): String = s"${c.symbol}$amount"
  def main(args: Array[String]): Unit = {
    println(price(50))
  }
}

Tvetydighetsfel

Om två implicita värden av samma typ finns i scopet rapporterar kompilatorn ett fel om tvetydigt implicit värde. Ha högst ett per typ eller skicka värdet explicit.

object Main {
  def label(x: Int)(implicit unit: String): String = s"$x$unit"
  implicit val unit: String = "px"
  def main(args: Array[String]): Unit = {
    // Only one implicit String in scope -> no ambiguity
    println(label(12))
  }
}

Beteende som liknar standardvärden

Implicit-parametrar ger en form av kontextmedvetna standardvärden: samma funktionsanrop kan ge olika resultat beroende på vilket implicit värde som finns i scopet.

object Main {
  def format(n: Double)(implicit decimals: Int): String =
    f"$n%.${decimals}f"
  implicit val d: Int = 2
  def main(args: Array[String]): Unit = {
    println(format(3.14159))
    println(format(3.14159)(4))
  }
}

Använd implicita värden sparsamt

Implicit-parametrar är kraftfulla men kan göra koden svårare att följa om de används för mycket. Använd dem för verklig genomgående kontext, till exempel exekveringskontexter, konfigurationer och instanser av typklasser.

object Main {
  case class Locale(code: String)
  def hello()(implicit loc: Locale): String =
    if (loc.code == "tr") "Merhaba" else "Hello"
  implicit val loc: Locale = Locale("tr")
  def main(args: Array[String]): Unit = {
    println(hello())
  }
}

Snabb kontroll

Hur avgör kompilatorn vilket värde som ska tillhandahållas för en implicit parameter?

Sammanfattning

Ni har lärt Er om implicit-parametrar (Scala 2-stil):

  • Markera en parameterlista med implicit för att fylla i den automatiskt
  • Upplösningen sker efter typ, som måste vara unik i scopet
  • implicitly[T] hämtar ett värde; kontextbundenheter [T: TC] är syntaktiskt socker
  • Sökningen omfattar lokalt scope, importer och companion objects
  • Använd dem för genomgående kontext, inte för allt
Gratis att börja

Lär dig Scala med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
39
Lektioner
143

Vanliga frågor

Är lektionen ”Implicita parametrar” gratis?

Ja – hela texten till ”Implicita parametrar” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Scala för backendutveckling och funktionell programmering, kan Ni uppgradera till CoddyKit PRO. Kursen i Scala för backendutveckling och funktionell programmering innehåller totalt 4 lektioner.

Vad lär jag mig i ”Implicita parametrar”?

Skicka kontext. Ni övar på Scala för backendutveckling och funktionell programmering med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Scala för backendutveckling och funktionell programmering?

Du behöver inga förkunskaper. Utbildningen i Scala för backendutveckling och funktionell programmering på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Implicita parametrar”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Scala för backendutveckling och funktionell programmering-lektionen?

Ja. Varje Scala för backendutveckling och funktionell programmering-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Implicita parametrar
  2. Scala 3 given/using
  3. Implicita konverteringar
  4. Extension-metoder
← Tillbaka till Scala för backendutveckling och funktionell programmering