2010-06-25 10 views
47

Trong C# bạn có thể viết:Scala tương đương với các phương pháp mở rộng của 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()); 
    } 
}} 

Làm thế nào sẽ extension method nhìn này đơn giản như trong Scala?

Trả lời

60

Các mô hình Pimp My Library là việc xây dựng tương tự:

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) 

} 

comments mỗi @Daniel Spiewak, điều này sẽ tránh được phản ánh trên phương pháp gọi, hiệu suất giúp đỡ:

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

Cảnh báo: bằng cách sử dụng 'cái mới {...} 'cú pháp, bạn đang thực sự gây ra trình biên dịch để suy ra một loại cấu trúc cho môi trường' phương pháp richInt', ý nghĩa rằng bất kỳ invocations của 'square' sẽ được thực hiện bằng cách sử dụng phản ánh (một kẻ giết người hiệu suất). Sẽ tốt hơn nếu định nghĩa một lớp 'RichInt' định nghĩa' square' và được trả về từ phương thức 'richInt'. –

+0

@Daniel, bạn có thể đăng mã mà bạn mô tả không? – OscarRyz

+4

@Support Thêm 'lớp RichInt (i: Int) {def square = i * i}' vào 'MyExtensions' và làm' mới RichInt (i) 'trên phương thức' richInt'. –

3

Trong Scala chúng tôi sử dụng cái gọi là (bởi người phát minh ra ngôn ngữ) Pimp Thư viện của tôi mẫu, được thảo luận nhiều và đẹp sy để tìm trên Web, nếu bạn sử dụng tìm kiếm chuỗi (không phải từ khóa).

9

Đây sẽ là mã sau số comment của Daniel.

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

Kể từ phiên bản 2.10 của Scala, nó có thể làm cho toàn bộ một lớp đủ điều kiện để chuyển đổi ngầm

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

Bên cạnh đó, chúng ta có thể tránh tạo ra một thể hiện của kiểu mở rộng bằng cách để nó mở rộng AnyVal

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

Để biết thêm thông tin về các lớp học ngầm và AnyVal, hạn chế và quirks, tham khảo tài liệu chính thức:

01.
+0

Lưu ý rằng các trường hợp ** không thể được chú thích bằng từ khóa 'implicit', vì chúng có đối tượng đồng hành được tạo tự động. Để biết thêm thông tin, xem các liên kết tài liệu được cung cấp bởi @megri. – falconepl