174 votes

Ce qui est l’identificateur de Scala « implicitement » ?

J'ai vu une fonction nommée implicitly utilisé dans Scala exemples. Qu'en est-il et comment est-il utilisé?

Exemple ici:

scala> sealed trait Foo[T] { def apply(list : List[T]) : Unit }; object Foo {
     |                         implicit def stringImpl = new Foo[String] {
     |                             def apply(list : List[String]) = println("String")
     |                         }
     |                         implicit def intImpl = new Foo[Int] {
     |                             def apply(list : List[Int]) =  println("Int")
     |                         }
     |                     } ; def foo[A : Foo](x : List[A]) = implicitly[Foo[A]].apply(x)
defined trait Foo
defined module Foo
foo: [A](x: List[A])(implicit evidence$1: Foo[A])Unit

scala> foo(1)
<console>:8: error: type mismatch;
 found   : Int(1)
 required: List[?]
       foo(1)
           ^
scala> foo(List(1,2,3))
Int
scala> foo(List("a","b","c"))
String
scala> foo(List(1.0))
<console>:8: error: could not find implicit value for evidence parameter of type
 Foo[Double]
       foo(List(1.0))
          ^

Notez que nous avons à écrire implicitly[Foo[A]].apply(x) depuis le compilateur pense que implicitly[Foo[A]](x) signifie que nous appelons implicitly avec des paramètres.

Voir aussi Comment enquêter sur les objets de/types de/etc. Scala REPL? et d'Où vient Scala recherchez implicites?

223voto

oluies Points 7682

``est disponible en Scala 2.8 et est défini dans Predef comme :

Il est couramment utilisé pour vérifier si une valeur implicite type `` est disponible et le retourner si tel est le cas.

Exemple simple de Présentation de retronyms )

210voto

retronym Points 35066

Voici quelques raisons d'utiliser le délicieusement simple méthode implicitly.

Pour comprendre/résoudre Implicite Vues

Implicite de Vue peut être déclenchée lorsque le préfixe de sélection (par exemple, the.prefix.selection(args) ne contient pas un membre de l' selection qui est applicable à la args (même après avoir essayé de convertir args avec les points de Vue). Dans ce cas, le compilateur recherche pour les membres implicites, définies localement dans le courant ou en joignant étendues, hérité, ou importés, qui sont Fonctions du type de l' the.prefix à un type avec selection défini, ou l'équivalent implicite des méthodes.

scala> 1.min(2) // Int doesn't have min defined, where did that come from?                                   
res21: Int = 1

scala> implicitly[Int => { def min(i: Int): Any }]
res22: (Int) => AnyRef{def min(i: Int): Any} = <function1>

scala> res22(1) // 
res23: AnyRef{def min(i: Int): Int} = 1

scala> .getClass
res24: java.lang.Class[_] = class scala.runtime.RichInt

Implicite points de Vue peut également être déclenchée lorsqu'une expression n'est pas conforme au Type Attendu, comme ci-dessous:

scala> 1: scala.runtime.RichInt
res25: scala.runtime.RichInt = 1

Ici, le compilateur recherche pour cette fonction:

scala> implicitly[Int => scala.runtime.RichInt]
res26: (Int) => scala.runtime.RichInt = <function1>

L'accès à un Paramètre Implicite Introduit par un Contexte Lié

Paramètres implicites sont sans doute un élément plus important de la Scala qu'Implicite points de Vue. Ils ont en charge le type de la classe de modèle. La bibliothèque standard utilise dans quelques endroits, voir scala.Ordering et comment il est utilisé dans SeqLike#sorted. Paramètres implicites sont également utilisés pour passer de la Matrice se manifeste, et CanBuildFrom des cas.

Scala 2.8 permet une abréviation de la syntaxe pour les paramètres implicites, appelé Contexte de Limites. Brièvement, une méthode avec un paramètre de type A qui nécessite un paramètre implicite de type M[A]:

def foo[A](implicit ma: M[A])

peut être réécrit comme suit:

def foo[A: M]

Mais quel est le point de passer le paramètre implicite, mais ne pas le nommer? Comment cela peut-il être utile lors de la mise en œuvre de la méthode de foo?

Souvent, le paramètre implicite n'a pas besoin d'être renvoyé directement, il sera passé à travers implicite d'argument à une autre méthode qui est appelée. Si c'est nécessaire, vous pouvez toujours conserver le laconique signature de la méthode avec le Contexte Lié, et appelez - implicitly pour matérialiser la valeur:

def foo[A: M] = {
   val ma = implicitly[M[A]]
}

Le passage d'un sous-ensemble de paramètres implicites explicitement

Supposons que vous appelez une méthode assez imprime une personne, à l'aide d'un type de classe de l'approche fondée sur:

trait Show[T] { def show(t: T): String }
object Show {
  implicit def IntShow: Show[Int] = new Show[Int] { def show(i: Int) = i.toString }
  implicit def StringShow: Show[String] = new Show[String] { def show(s: String) = s }

  def ShoutyStringShow: Show[String] = new Show[String] { def show(s: String) = s.toUpperCase }
}

case class Person(name: String, age: Int)
object Person {
  implicit def PersonShow(implicit si: Show[Int], ss: Show[String]): Show[Person] = new Show[Person] {
    def show(p: Person) = "Person(name=" + ss.show(p.name) + ", age=" + si.show(p.age) + ")"
  }
}

val p = Person("bob", 25)
implicitly[Show[Person]].show(p)

Si nous voulons changer la façon dont le nom est sortie? Nous pouvons appeler explicitement PersonShow, transmettre explicitement une alternative Show[String], mais nous voulons que le compilateur pour passer l' Show[Int].

Person.PersonShow(si = implicitly, ss = Show.ShoutyStringShow).show(p)

-4voto

Randall Schulz Points 18820

"Vous apprendre à pêcher", la réponse est d'utiliser le classement alphabétique index de membre actuellement disponibles dans le Scaladoc nightlies. Les lettres (et l' #, pour les non-alphabétique des noms) dans la partie supérieure de l'emballage / classe volet sont les liens de l'index pour les noms commençant par cette lettre (dans toutes les classes). Si vous choisissez I, par exemple, vous trouverez de l' implicitly entrée avec un événement, en Predef, que vous pouvez visiter à partir du lien.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X