0Pricing
Scala for Backend Engineering & Functional Programming · Lezione

Parametri impliciti

Passaggio del contesto

Parametri impliciti è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Scala for Backend Engineering & Functional Programming, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.

Passare automaticamente il contesto

I parametri impliciti consentono al compilatore di fornire automaticamente un argomento, scelto tra i valori contrassegnati come implicit nell'ambito. Sono ideali per passare un contesto «ambientale», come la configurazione o le regole di formattazione.

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"))
  }
}

L'elenco dei parametri impliciti

Contrassegni l'ultimo elenco di parametri con la parola chiave implicit. Quando lo omette nel punto della chiamata, il compilatore cerca un valore implicito corrispondente.

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))
  }
}

Fornire esplicitamente gli impliciti

È sempre possibile passare un parametro implicito in modo esplicito, sostituendo quello presente nell'ambito. È utile nei casi isolati.

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))
  }
}

Risoluzione degli impliciti per tipo

Il compilatore abbina gli impliciti in base al tipo, non al nome. Nell'ambito deve esserci esattamente un valore implicito corrispondente; in caso contrario, la compilazione fallisce perché il valore è ambiguo o manca.

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 per ottenere un valore

L'helper implicitly[T] recupera direttamente dall'ambito il valore implicito di tipo T, senza dover nominare un parametro.

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

Forma abbreviata con context bound

Un context bound [T: Ordering] è una forma abbreviata per un parametro implicito di tipo Ordering[T]. È comune con i type class.

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"))
  }
}

Trasmettere il contesto attraverso le chiamate

I parametri impliciti sono particolarmente utili quando molte funzioni richiedono lo stesso contesto. Lo si contrassegna una volta come implicito e il contesto viene trasmesso automaticamente attraverso le chiamate annidate.

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()
  }
}

Dove vengono cercati gli impliciti

Il compilatore cerca gli impliciti nell'ambito locale, negli import e negli oggetti companion dei tipi coinvolti. Gli oggetti companion sono un luogo ordinato in cui fornire valori predefiniti.

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))
  }
}

Errori di ambiguità

Se nell'ambito sono presenti due impliciti dello stesso tipo, il compilatore segnala un errore di implicito ambiguo. Mantenga al massimo un implicito per tipo oppure lo passi esplicitamente.

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))
  }
}

Comportamento simile ai valori predefiniti

I parametri impliciti forniscono una forma di valori predefiniti sensibili al contesto: la stessa chiamata di funzione produce risultati diversi a seconda dell'implicito presente nell'ambito.

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))
  }
}

Usare gli impliciti con moderazione

I parametri impliciti sono potenti, ma se usati eccessivamente possono rendere il codice più difficile da seguire. Li riservi a contesti realmente trasversali, come execution context, configurazioni e istanze di type class.

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())
  }
}

Verifica rapida

Come decide il compilatore quale valore fornire per un parametro implicito?

Riepilogo

Ha imparato a conoscere i parametri impliciti (stile Scala 2):

  • Contrassegni un elenco di parametri con implicit per farlo compilare automaticamente
  • La risoluzione avviene per tipo, che deve essere unico nell'ambito
  • implicitly[T] recupera un valore; i context bound [T: TC] sono una forma abbreviata
  • La ricerca comprende l'ambito locale, gli import e gli oggetti companion
  • Li usi per i contesti trasversali, non per qualsiasi cosa

Domande Frequenti

La lezione «Parametri impliciti» è gratuita?

Sì — il testo completo di «Parametri impliciti» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Scala for Backend Engineering & Functional Programming, passa a CoddyKit PRO. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.

Cosa imparerò in «Parametri impliciti»?

Passaggio del contesto Eserciti Scala for Backend Engineering & Functional Programming con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Scala for Backend Engineering & Functional Programming?

Non è richiesta alcuna esperienza precedente. Scala for Backend Engineering & Functional Programming su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Parametri impliciti»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Scala for Backend Engineering & Functional Programming?

Sì. Ogni lezione Scala for Backend Engineering & Functional Programming include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Parametri impliciti
  2. given/using in Scala 3
  3. Conversioni implicite
  4. Metodi di estensione
← Torna a Scala for Backend Engineering & Functional Programming