2010-06-25 18 views
47

In C# können Sie schreiben:Scala entspricht den Erweiterungsmethoden von 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()); 
    } 
}} 

Wie würde diese einfachen extension method aussieht wie in Scala?

Antwort

60

Das Pimp My Library Muster ist die analoge Konstruktion:

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) 

} 

Per @ Daniel Spiewak Kommentare, diese Reflexion über Methodenaufruf zu vermeiden, Beihilfe Leistung:

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

Achtung: unter Verwendung der 'neue {...}' Syntax, die Sie tatsächlich verursacht, den Compiler einen Strukturtyp für die 'richInt' Verfahren abzuleiten, bedeutung dass alle Aufrufe von 'square' mit Reflektion (einem Performance Killer) erfolgen. Es wäre besser, eine 'RichInt'-Klasse zu definieren, die' square' definiert und von der 'richInt'-Methode zurückgegeben wird. –

+0

@Daniel, könnten Sie den Code schreiben, den Sie beschreiben? – OscarRyz

+4

@Support Füge 'class RichInt (i: Int) {def square = i * i}' zu 'MyExtensions' hinzu und mache' new RichInt (i) 'auf der' richInt' Methode. –

3

In Scala wir verwenden der sogenannte (vom Erfinder der Sprache) Pimp My Library Muster, das viel diskutiert wird und ziemlich ea sy im Web zu finden, wenn Sie eine Suche nach einem String (nicht Keyword) verwenden.

9

Dies wäre der Code nach 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

Seit der Version 2.10 von Scala ist es möglich, eine ganze Klasse, die für implizite Konvertierung

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

Zusätzlich zu machen, ist es möglich, eine Instanz des Erweiterungstypen zu vermeiden, die Schaffung von ihm mit verlängern AnyVal

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

weitere Informationen über implizite Klassen und AnyVal, Beschränkungen und Macken, finden Sie in der offiziellen Dokumentation:

+0

Beachten Sie, dass Fallklassen ** nicht mit einem impliziten Schlüsselwort versehen werden können, da sie automatisch generierte Begleitobjekte enthalten. Weitere Informationen finden Sie in den von @megri bereitgestellten Dokumentationslinks. – falconepl

Verwandte Themen