Je voudrais ajouter une méthode à un type intégré (par exemple Double), de sorte que je puisse utiliser un opérateur infix
. Est-ce possible?Est-il possible d'ajouter une méthode à un type intégré dans Scala?
Répondre
Oui et non. Oui, vous pouvez le faire semblent comme si vous avez ajouté une méthode à double
. Par exemple:
class MyRichDouble(d: Double) {
def <>(other: Double) = d != other
}
implicit def doubleToSyntax(d: Double) = new MyRichDouble(d)
Ce code ajoute l'opérateur <>
précédemment indisponibles pour tout objet de type Double
. Tant que la méthode doubleToSyntax
est portée afin qu'il puisse être invoqué sans qualification, ce qui suit fonctionnera:
3.1415 <> 2.68 // => true
Le « non » une partie de la réponse vient du fait que vous n'êtes pas vraiment rien ajouter à la classe Double
. Au lieu de cela, vous créez une conversion de Double
à un nouveau type qui définit la méthode que vous souhaitez. Cela peut être une technique beaucoup plus puissante que les classes ouvertes offertes par de nombreux langages dynamiques. Il arrive aussi à être complètement sûr de type. :-)
Certaines limitations que vous devez être au courant:
- Cette technique ne vous permet pas de supprimer ou redéfinissent méthodes existantes, il suffit d'ajouter de nouvelles
- La méthode de conversion implicite (dans ce cas,
doubleToSyntax
) doit absolument être dans le champ d'application pour que la méthode d'extension désirée soit disponible
Idiomatiquement, implicitement c Les inversions sont placées dans des objets singleton et importées (par ex. import Predef._
) ou au sein des traits et hérités (par exemple, class MyStuff extends PredefTrait
). Légèrement à part: les "opérateurs infixes" dans Scala sont en fait des méthodes. Il n'y a pas de magie associée à la méthode <>
qui lui permet d'être infixe, l'analyseur l'accepte simplement comme ça. Vous pouvez également utiliser des "méthodes régulières" comme opérateurs infix si vous le souhaitez. Par exemple, la classe Stream
définit une méthode take
qui prend un seul paramètre Int
et renvoie un nouveau Stream
. Ceci peut être utilisé de la manière suivante:
val str: Stream[Int] = ...
val subStream = str take 5
L'expression str take 5
est littéralement identique à str.take(5)
.
Cette fonction est bien pratique pour mettre en œuvre une estimation d'erreur performante de classe:
object errorEstimation {
class Estimate(val x: Double, val e: Double) {
def + (that: Estimate) =
new Estimate(this.x + that.x, this.e + that.e)
def - (that: Estimate) =
new Estimate(this.x - that.x, this.e + that.e)
def * (that: Estimate) =
new Estimate(this.x * that.x,
this.x.abs*that.e+that.x.abs*this.e+this.e*that.e)
def/(that: Estimate) =
new Estimate(this.x/that.x,
(this.x.abs*that.e+that.x.abs*this.e)/(that.x.abs*(that.x.abs-that.e)))
def +- (e2: Double) =
new Estimate(x,e+e2)
override def toString =
x + " +- " + e
}
implicit def double2estimate(x: Double): Estimate = new Estimate(x,0)
implicit def int2estimate(x: Int): Estimate = new Estimate(x,0)
def main(args: Array[String]) = {
println(((x: Estimate) => x+2*x+3*x*x)(1 +- 0.1))
// 6.0 +- 0.93
println(((x: Estimate) => (((y: Estimate) => y*y + 2)(x+x)))(1 +- 0.1))
// 6.0 +- 0.84
def poly(x: Estimate) = x+2*x+3/(x*x)
println(poly(3.0 +- 0.1))
// 9.33333 +- 0.3242352
println(poly(30271.3 +- 0.0001))
// 90813.9 +- 0.0003
println(((x: Estimate) => poly(x*x))(3 +- 1.0))
// 27.037 +- 20.931
}
}
C'est en fait un peu soigné. :) –
- 1. Conversion explicite Type Scala
- 2. Méthode générique avec un type non spécifié possible?
- 3. Est-il possible d'écrire une boucle dans Scala Console?
- 4. Est-il possible d'appeler une méthode sur le type que vous transmettez dans votre méthode générique?
- 5. Comment définir une méthode dans un type anonyme?
- 6. scala: comment créer un type générique qui est sous-type de toutes les classes numériques dans scala afin qu'il puisse inclure la méthode de comparaison
- 7. Comment faire référence au type conteneur dans une méthode sur un type construit d'exécution?
- 8. Comment instancier une instance de type représenté par le paramètre de type à Scala
- 9. Comment trier un tableau dans Scala?
- 10. Comment configurer plusieurs limites de type dans Scala?
- 11. Peut-on associer une gamme à Scala?
- 12. Est-il possible d'envoyer une méthode d'objet à une fonction?
- 13. Y at-il une fonction pour vérifier si un objet est un type de données intégré?
- 14. Est-il possible de créer une méthode de type dans Delphi?
- 15. ne peut pas comprendre les erreurs de type à Scala
- 16. Comment imprimer une carte dans Scala
- 17. Construire un java.util.List à partir d'un java.util.Set dans Scala
- 18. Comment copier une liste dans Scala
- 19. Comment convertir une variable dans Scala?
- 20. Scala: Comment "stocker" une fonction dans un var?
- 21. Création d'un type de graphique paramétrique dans Scala
- 22. Est-il possible de remplacer une méthode dans une classe dans un fichier dll?
- 23. Comment retourner un type générique via une méthode dans une classe de base?
- 24. Transmettre le type de variable à une méthode sans énumérer
- 25. Récupère la valeur de fonction d'une méthode d'instance dans Scala
- 26. Est-il possible d'avoir un test de charge Ocracoke intégré dans un MSBuild?
- 27. Comment appeler une méthode générique avec un objet Type donné?
- 28. Ajouter un aspect à une méthode abstraite?
- 29. Existe-t-il une méthode de type zip dans .Net?
- 30. Comment Scala peut-il recevoir plusieurs paramètres dans une définition de méthode?
Vous pouvez utiliser la syntaxe 'class' implicite pour simplifier un peu. – lmm