2010-06-25 13 views
47

In C# è possibile scrivere:Scala equivalente dei metodi di estensione di 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()); 
    } 
}} 

Come sarebbe questo semplice extension method assomigliare a Scala?

risposta

60

Il Pimp My Library modello è la costruzione analoga:

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) 

} 

commenti di Per @ Daniel Spiewak, questo eviterà riflessione sulla chiamata di metodo, le prestazioni favoreggiamento:

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

Attenzione: utilizzando il nuovo {...} 'la sintassi, si sta effettivamente facendo il compilatore di dedurre un tipo strutturale per il metodo' richInt' significato ' che ogni invocazione di 'square' sarà fatta usando la reflection (un killer della performance). Sarebbe meglio definire una classe 'RichInt' che definisce' square' e viene restituita dal metodo 'richInt'. –

+0

@Daniel, potresti pubblicare il codice che stai descrivendo? – OscarRyz

+4

@Support Aggiungi 'class RichInt (i: Int) {def square = i * i}' a 'MyExtensions' e fai' new RichInt (i) 'nel metodo' richInt'. –

3

In Scala usiamo il cosiddetto (dall'inventore della lingua) Pimp My Library modello, che è molto discusso e piuttosto EA cercare sul Web, se si utilizza una ricerca stringa (non parola chiave).

9

Questo sarebbe il codice dopo Daniel's 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

Dalla versione 2.10 di Scala, è possibile effettuare una intera classe idonei per la conversione implicita

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

Inoltre, è possibile evitare di creare un'istanza del tipo di estensione da averlo estendere AnyVal

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

Per ulteriori informazioni sulle classi implicite e AnyVal, limitazioni e stranezze, consultare la documentazione ufficiale:

+0

Si noti che le classi di casi ** non possono ** essere annotate con la parola chiave 'implicit', perché hanno un oggetto companion generato automaticamente. Per ulteriori informazioni consultare i collegamenti alla documentazione forniti da @megri. – falconepl

Problemi correlati