Definire istanze
Istanze implicite
Definire istanze è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 2 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.
Definire le istanze
Un'instance indica al compilatore come si comporta una classe di tipi per un tipo specifico. In Scala, le istanze sono generalmente contrassegnate come implicit (Scala 2) oppure dichiarate con given (Scala 3), così vengono individuate automaticamente.
Un'istanza implicit val
Per una classe di tipi semplice è sufficiente un implicit val. Il compilatore lo individua quando una funzione richiede un Show[Int].
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => s"Int=$a"
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(123))
}
}implicitly: richiamare un'istanza
implicitly[Show[Int]] chiede al compilatore di recuperare l'istanza disponibile nell'ambito corrente. È utile per verificare che un'istanza esista o per accedervi direttamente.
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => s"<$a>"
def main(args: Array[String]): Unit = {
val s = implicitly[Show[Int]]
println(s.show(8))
}
}Istanze per tipi personalizzati
Definisca un'istanza per la propria case class. La classe dei dati rimane pulita; la formattazione risiede nell'istanza.
trait Show[A] { def show(a: A): String }
case class Point(x: Int, y: Int)
object Main {
implicit val pointShow: Show[Point] = (p: Point) => s"(${p.x}, ${p.y})"
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(Point(3, 4)))
}
}implicit def per le istanze generiche
Quando un'istanza dipende da un'altra istanza, usi implicit def. Qui un Show[List[A]] viene costruito a partire da un Show[A].
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => a.toString
implicit def listShow[A](implicit s: Show[A]): Show[List[A]] =
(xs: List[A]) => xs.map(s.show).mkString("[", ", ", "]")
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(List(1, 2, 3)))
}
}Istanze nell'oggetto companion
Collocare le istanze nel companion object della classe di tipi fa sì che vengano individuate automaticamente senza alcun import. È il posto consigliato per le istanze predefinite.
trait Show[A] { def show(a: A): String }
object Show {
implicit val intShow: Show[Int] = (a: Int) => s"i:$a"
implicit val strShow: Show[String] = (a: String) => s"s:$a"
}
object Main {
def display[A](a: A)(implicit s: Show[A]): String = s.show(a)
def main(args: Array[String]): Unit = {
println(display(5))
println(display("hi"))
}
}Ambito e priorità degli impliciti
Il compilatore cerca un'istanza in diversi punti: prima nell'ambito locale o importato, poi nei companion object dei tipi coinvolti. Se due istanze sono ugualmente specifiche, si verifica un errore di implicit ambiguo.
Forma abbreviata del context bound
La sintassi def f[A: Show](a: A) è un context bound: significa che nell'ambito deve essere presente un Show[A] implicito. All'interno, lo recuperi con implicitly.
trait Show[A] { def show(a: A): String }
object Main {
implicit val intShow: Show[Int] = (a: Int) => s"n=$a"
def display[A: Show](a: A): String = implicitly[Show[A]].show(a)
def main(args: Array[String]): Unit = {
println(display(77))
}
}Un helper per richiamare le istanze
Le librerie aggiungono un metodo apply al companion come comodo summoner: Show[Int] restituisce l'istanza. È più pulito di implicitly.
trait Show[A] { def show(a: A): String }
object Show {
def apply[A](implicit s: Show[A]): Show[A] = s
implicit val intShow: Show[Int] = (a: Int) => s"=$a"
}
object Main {
def main(args: Array[String]): Unit = {
println(Show[Int].show(10))
}
}Evitare le istanze orfane
Un'istanza orfana è definita al di fuori sia della classe di tipi sia del tipo. È legale, ma può causare comportamenti incoerenti tra gli import. Preferisca le istanze nei companion object per mantenerle coerenti.
Riunire tutti gli elementi
Un programma completo: istanze nei companion object, un'istanza derivata per le liste e un summoner.
trait Show[A] { def show(a: A): String }
object Show {
def apply[A](implicit s: Show[A]): Show[A] = s
implicit val intShow: Show[Int] = _.toString
implicit def listShow[A](implicit s: Show[A]): Show[List[A]] =
(xs: List[A]) => xs.map(s.show).mkString(", ")
}
object Main {
def main(args: Array[String]): Unit = {
println(Show[List[Int]].show(List(4, 5, 6)))
}
}Verifica rapida
Verifichi la sua conoscenza della definizione delle istanze.
Riepilogo
Ha imparato a definire le istanze:
implicit valper le istanze semplici,implicit defper quelle derivate.- Richiami un'istanza con
implicitlyo con unapplydel companion. - Usi i context bound
[A: Show]come forma abbreviata. - Inserisca le istanze nei companion object per evitare istanze orfane.
Domande Frequenti
La lezione «Definire istanze» è gratuita?
Sì — il testo completo di «Definire istanze» è 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 «Definire istanze»?
Istanze implicite 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 2 di 4.
Quanto tempo richiede la lezione «Definire istanze»?
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.