2014-07-21 15 views
7

Cập nhật: Swift 3 cho phép Self được sử dụng từ các loại khác, nhờ SE-0068 – Expanding Swift Self to class members and value types.'Tự' chỉ khả dụng trong giao thức hoặc do kết quả của phương thức lớp

Bạn có thể trở về "Tự" từ một chức năng lớp:

extension NSObject { 
    class func makeOne() -> Self { 
     return self() 
    } 
} 

Vì vậy, bạn có thể làm:

let set : NSCountedSet = NSCountedSet.makeOne() 

Tuy nhiên, hai sau đây không biên dịch:

extension NSObject { 
    class func makeTwo() -> (Self, Self) { 
     return (self(), self()) 
    } 

    class func makeMany() -> [Self] { 
     return [self(), self(), self(), self(), self()] 
    } 
} 

Lỗi này là:

<REPL>:11:34: error: 'Self' is only available in a protocol or as the result of a class method; did you mean 'NSObject'? 
     class func makeTwo() -> (Self, Self) { 
           ^~~~ 
           NSObject 
<REPL>:11:40: error: 'Self' is only available in a protocol or as the result of a class method; did you mean 'NSObject'? 
     class func makeTwo() -> (Self, Self) { 
             ^~~~ 
             NSObject 
<REPL>:15:35: error: 'Self' is only available in a protocol or as the result of a class method; did you mean 'NSObject'? 
     class func makeMany() -> [Self] { 
            ^~~~ 
            NSObject 

Có ai biết cách nào để khai báo rằng một hàm lớp trả về nhiều phiên bản của chính lớp đó không?

+0

Đáng chú ý rằng không có lý do thực sự tại sao không thể thực hiện được - cho phương thức tĩnh '() -> Self' đã cho trên một loại đã cho' T', trình biên dịch chỉ tạo ra một hàm '(T.Type) -> T'. Khi được gọi, người gọi chỉ đưa kết quả vào loại thực tế mà phương thức được gọi. Trình biên dịch có thể thực hiện việc chuyển đổi một mảng các cá thể lớp con thành một mảng các cá thể siêu lớp và việc chuyển đổi tuple có thể được thực hiện một cách trivially bằng cách phân tách. Vì vậy, trong khi nó là một cái gì đó về mặt kỹ thuật trình biên dịch * có thể * làm, nó chỉ không hỗ trợ nó (chưa). – Hamish

Trả lời

4

Vấn đề, tôi nghi ngờ, đó là tự mơ hồ; nó có nghĩa là "lớp này hoặc phân lớp, bất kể điều gì xảy ra là vào thời điểm chúng tôi được gọi là". Nói cách khác, Self là đa hình. Nhưng bạn không thể tạo một mảng bao gồm hai lớp khác nhau, ví dụ. Và mặc dù lớp có thể cho phép một bộ khởi tạo nhất định, chúng ta không thể biết trước rằng lớp con của nó sẽ.

Giải pháp là sử dụng tên lớp của chính nó. Dưới đây là ví dụ về cấu trúc Thing:

extension Thing { 
    static func makeTwo() -> (Thing, Thing) { 
     return (Thing(), Thing()) 
    } 
} 
+0

Tôi có thể hiểu ví dụ 'Array', nhưng tại sao nó không cho phép' tuple'? –

+0

@LuisAscorbe Không chắc chắn những gì bạn đang yêu cầu. Lưu ý rằng đây là từ tháng 7 năm 2014! Ngôn ngữ Swift đã thay đổi rất nhiều kể từ đó. Nếu bạn có một câu hỏi mới liên quan đến mọi thứ bây giờ, bạn nên hỏi nó như một câu hỏi mới. – matt

+0

@matt bất kỳ thay đổi nào đối với điều này? Tôi rất muốn trả lại '[Tự]' từ một phần mở rộng (trên NSObject) ... [lưu ý rằng tôi đã cố gắng đặt câu hỏi một lần nữa nhưng đã đóng cửa như một dupe: stackoverflow.com/questions/43400022] ... cảm ơn ! –

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