2017-07-18 1 views
0

En Scala, si j'ai une classe appelée Vector2D et que je souhaite effectuer des conversions implicites pour cette classe. Actuellement, j'ai cette fonction placée dans le Vector2D: implicit def fromFloatTuple(tuple: (Float, Float)): Vector2D = new Vector2D(tuple._1, tuple._2)Fonction d'appel via la fonction implicite dans Scala

Je peux faire ce qui suit avec succès val x: Vector2D = (1f, 1f). Cependant, je ne peux pas faire quelque chose comme: val x: Float = (1f, 1f).length() (évidemment la longueur est définie pour Vector2D). Pourquoi cela ne fonctionne pas, je m'attendrais à ce qu'il soit converti en quelque chose comme val x: Float = fromFloatTuple((1f, 1f)).length() mais ce n'est pas le cas. Comment puis-je obtenir cet effet dans Scala? Aussi maintenant que j'y pense, comment faire pour que cette fonction accepte d'autres types numériques sans faire de fonction pour chaque combinaison de tous les types numériques (pas un problème avec un vecteur 2D mais assez sale pour un vecteur 4D)).

Répondre

-1

This is exactly how it is supposed to work:

import scala.language.implicitConversions 

object Test { 
    class Vector2D(x: Float, y: Float) { def length(): Float = x + y } 

    implicit def fromFloatTuple(tuple: (Float, Float)): Vector2D = Vector2D(tuple._1, tuple._2) 

    val x: Float = (1f, 1f).length() 

Pour le cas plus générique, vous voudrez peut-être regarder scala.math.Numeric.

case class Vector4D[N](a: N, b: N, c: N, d: N)(implicit n: Numeric[N]) { 
    import n._ 

    def length(): N = a + b + c + d 
    } 

    implicit def c2V4D[N: Numeric](tup: (N, N, N, N)): Vector4D[N] = new Vector4D(tup._1, tup._2, tup._3, tup._4) 

    println(Vector4D(1,2,3,4).length()) 
    println(Vector4D(1,2,3,4.5).length()) 
    println((1,2,3,4).length()) 
} 
+0

Bien que ce lien peut répondre à la question, il est préférable d'inclure les éléments essentiels de la réponse ici et de fournir le lien de référence. Les réponses à lien uniquement peuvent devenir invalides si la page liée change. - [De l'avis] (/ review/low-quality-posts/16747601) – stevieb

+0

Merci pour les commentaires! –

+0

Cela échoue pour un cas comme '(1f, 1)' car ils sont de types numériques différents. Une solution de contournement serait cependant de déclarer plusieurs arguments génériques. –

1

Lorsque vous avez le type de cible ou d'une source Vector2D, le compilateur regarde dans l'objet compagnon de Vector2D; dans val x: Float = (1f, 1f).length() ce n'est pas le cas. Chercher tous les types possibles pour la conversion implicite ralentirait beaucoup la compilation, et le compilateur Scala est déjà lent (bien qu'améliorer).

Vous devez apporter fromFloatTuple dans le périmètre en l'important:

import your.package.Vector2D._ // or just fromFloatTuple instead of _