2014-06-25 16 views
24

Có cú pháp hoặc kỹ thuật tương đương cho lớp Ẩn danh trong Swift không? Chỉ để làm rõ Lớp ẩn danh trong ví dụ Java tại đây - http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.htmlLớp vô danh trong swift

Cảm ơn!

+0

Không giống như vậy. Các lớp ẩn danh là một trong những tính năng Java ưa thích của tôi, vì vậy tôi hy vọng chúng ta có chúng trong Swift cuối cùng. – hpique

+0

@hpique Đúng, chúng rất tốt trong Java nhưng chúng không thực sự cần thiết trong các ngôn ngữ có các bao đóng và các lớp có thể được khai báo bên trong các phương thức. Tất cả các kiểu nghe/bộ điều hợp trong Java có thể được triển khai dễ dàng bằng cách sử dụng các bao đóng, không có các lớp ẩn danh. – Sulthan

+0

@Sulthan Chắc chắn, bạn có thể làm được rất nhiều với các bao đóng và các lớp bên trong. Nhưng với việc sử dụng rộng rãi các giao thức trong Swift, tôi nghĩ rằng các lớp ẩn danh có thể thực sự tiện dụng trong một số trường hợp. – hpique

Trả lời

12

Không có cú pháp tương đương, theo như tôi biết.

Về kỹ thuật tương đương, về mặt lý thuyết bạn có thể sử dụng bao đóng và xác định cấu trúc và lớp bên trong chúng. Đáng buồn thay, tôi không thể làm điều này để làm việc trong một sân chơi hoặc dự án mà không làm cho nó sụp đổ. Nhiều khả năng điều này chưa sẵn sàng để sử dụng trong bản beta hiện tại.

Cái gì đó như ...

protocol SomeProtocol { 
    func hello() 
} 

let closure :() ->() = { 
    class NotSoAnonymousClass : SomeProtocol { 
     func hello() { 
      println("Hello") 
     } 
    } 
    let object = NotSoAnonymousClass() 
    object.hello() 
} 

... hiện kết quả đầu ra lỗi này:

invalid linkage type for global declaration 
%swift.full_heapmetadata* @_TMdCFIv4Test7closureFT_T_iU_FT_T_L_19NotSoAnonymousClass 
LLVM ERROR: Broken module found, compilation aborted! 
Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 1 
+0

Được đánh dấu là đã được giải quyết nhưng vẫn có thể thử nghiệm trên beta2 – eranh

6

Không cú pháp lớp vô danh trong Swift. Tuy nhiên, bạn có thể tạo ra một lớp bên trong một lớp và lớp phương pháp:

class ViewController: UIViewController { 

    class anonymousSwiftClass { 
     func add(number1:Int, number2:Int) -> Int { 
      return number1+number2; 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     class innerSwiftClass { 
      func sub(number1:Int, number2:Int) -> Int { 
       return number1-number2; 
      } 
     } 

     var inner = innerSwiftClass(); 
     println(inner.sub(2, number2: 3)); 

     var anonymous = anonymousSwiftClass(); 
     println(anonymous.add(2, number2: 3)); 
    } 
} 
+0

Thời gian chạy rất kỳ quái. Một mặt, nó buộc bạn đặt các dấu ngoặc nhọn quanh các câu lệnh 'if' đơn dòng và để làm cho các câu lệnh chuyển đổi đầy đủ, nhưng đồng thời cho phép bạn định nghĩa toàn bộ lớp bên trong * body * của một phương thức. smh – devios1

8

Ví dụ, Java nghe/bộ chuyển đổi mô hình sẽ được dịch sang Swift như thế này:

protocol EventListener { 
    func handleEvent(event: Int) ->() 
} 

class Adapter : EventListener { 
    func handleEvent(event: Int) ->() { 
    } 
} 

var instance: EventListener = { 
    class NotSoAnonymous : Adapter { 
     override func handleEvent(event: Int) { 
      println("Event: \(event)") 
     } 
    } 

    return NotSoAnonymous() 
}() 

instance.handleEvent(10) 

(Đâm trình biên dịch trên Beta 2)

Vấn đề là bạn luôn phải chỉ định tên. Tôi không nghĩ rằng Apple sẽ bao giờ giới thiệu các lớp vô danh (và cấu trúc, vv) vì nó sẽ là khá khó khăn để đi kèm với một cú pháp mà không va chạm với các đóng đóng dấu.

Cũng trong lập trình, những điều vô danh là xấu. Đặt tên cho mọi thứ giúp người đọc hiểu mã.

+0

Tôi đồng ý rằng ẩn danh chương trình là xấu. Tôi cần nó cho mocks thử nghiệm.Cho rằng hiện tại không có khung mocking tốt, nó là quá nhiều đau đớn để phân lớp và mỗi mô hình. – eranh

8

Bạn cũng có thể tạo ra một lớp trống cơ bản mà hoạt động như một giao thức để trần, và thông qua một kết thúc với init chức năng đó sẽ ghi đè bất cứ điều gì bạn muốn, như thế này:

class EmptyClass { 

    var someFunc:() ->() = { } 

    init(overrides: EmptyClass -> EmptyClass) { 
     overrides(self) 
    } 
} 

// Now you initialize 'EmptyClass' with a closure that sets 
// whatever variable properties you want to override: 

let workingClass = EmptyClass { ec in 
    ec.someFunc = { println("It worked!") } 
    return ec 
} 

workingClass.someFunc() // Outputs: "It worked!" 

Nó không phải là về mặt kỹ thuật 'vô danh' nhưng nó hoạt động theo cùng một cách. Bạn được đưa ra một vỏ rỗng của một lớp, và sau đó bạn điền vào hoặc ghi đè lên bất kỳ tham số nào bạn muốn khi bạn khởi tạo nó với một đóng.

Về cơ bản nó giống nhau, ngoại trừ thay vì hoàn thành sự mong đợi của một giao thức, nó sẽ ghi đè các thuộc tính của một lớp.

+0

Rực rỡ. Cảm ơn. –

Các vấn đề liên quan