2010-06-25 8 views
47

En C# vous pouvez écrire:Scala équivalent des méthodes d'extension de C#?

using System.Numerics; 
namespace ExtensionTest { 
public static class MyExtensions { 
    public static BigInteger Square(this BigInteger n) { 
     return n * n; 
    } 
    static void Main(string[] args) { 
     BigInteger two = new BigInteger(2); 
     System.Console.WriteLine("The square of 2 is " + two.Square()); 
    } 
}} 

Comment serait-ce look simple extension method comme à Scala?

Répondre

60

Le modèle Pimp My Library est la construction analogue:

object MyExtensions { 
    implicit def richInt(i: Int) = new { 
    def square = i * i 
    } 
} 


object App extends Application { 
    import MyExtensions._ 

    val two = 2 
    println("The square of 2 is " + two.square) 

} 

commentaires de Per @ Daniel Spiewak, cela évitera une réflexion sur l'invocation de la méthode, aider la performance:

object MyExtensions { 
    class RichInt(i: Int) { 
    def square = i * i 
    } 
    implicit def richInt(i: Int) = new RichInt(i) 
} 
+28

Attention: en utilisant le 'nouveau {...}' syntaxe, vous causez en fait le compilateur de déduire un type de structure pour la méthode 'richInt', sens que toute invocation de 'square' sera faite en utilisant la réflexion (un tueur de performance). Il vaudrait mieux définir une classe 'RichInt' qui définit' square' et qui est retournée par la méthode 'richInt'. –

+0

@Daniel, pourriez-vous poster le code que vous décrivez? – OscarRyz

+4

@Support Ajoutez la classe RichInt (i: Int) {def square = i * i} 'à MyExtensions et faites' new RichInt (i) 'sur la méthode' richInt'. –

3

En Scala nous utilisons le soi-disant (par l'inventeur de la langue) Pimp My Library motif, qui est beaucoup discuté et jolie ea sy à trouver sur le Web, si vous utilisez une recherche de chaîne (pas de mot-clé).

9

Ce serait le code après Daniel comment.

object MyExtensions { 
    class RichInt(i: Int) { 
     def square = i * i 
    } 
    implicit def richInt(i: Int) = new RichInt(i) 

    def main(args: Array[String]) { 
     println("The square of 2 is: " + 2.square) 
    } 
} 
45

Depuis la version 2.10 de Scala, il est possible de faire toute une classe admissible à une conversion implicite

implicit class RichInt(i: Int) { 
    def square = i * i 
} 

En outre, il est possible d'éviter la création d'une instance du type d'extension en le faisant étendre AnyVal

implicit class RichInt(val i: Int) extends AnyVal { 
    def square = i * i 
} 

Pour plus d'informations sur les classes implicites et AnyVal, les limites et les bizarreries, consultez la documentation officielle:

+0

Notez que les classes de cas ** ne peuvent pas ** être annotées avec le mot clé 'implicit', car elles ont un objet compagnon généré automatiquement. Pour plus d'informations, consultez les liens de documentation fournis par @megri. – falconepl