2014-12-16 14 views
9

Self może być używany jako typ zwracanej przez metodę:samodzielnego stosowania jako typ rodzajowy

func doSomething() -> Self {} 

czy to jakoś możliwe użycie Self jako ogólny typu jak ten?

func doSomething() -> Wrapper<Self> {} 

Przykład

Byłoby miło gdybym mógł podklasy ChristmasPresent i niech mają wrapped funkcję zwracającą WrappedPresent z rodzajowego zestawu do cokolwiek podklasa było.

class ChristmasPresent { 
    func wrapped() -> WrappedPresent<Self> { 
     return WrappedPresent(present: self) 
    } 
} 

class WrappedPresent<T: ChristmasPresent> { 
    var present: T 

    init(present: T) { 
     self.present = present 
    } 
} 

class ToyCar: ChristmasPresent {} 

let wrappedToyCar = ToyCar().wrapped() // Inferred to be: WrappedPresent<ToyCar> 
+0

Co oznaczałoby to ograniczenie? Gdzie jest zarejestrowane to ogólne ograniczenie? Jak deklaruje się Wrapper? Jeśli jest to 'Wrapper ', możemy zwrócić 'Wrapper ', maybe .. – cmyr

+0

Czy istnieje powód, dla którego nie znasz typu "Self" w tym czasie? Może po prostu nie myślę wystarczająco mocno. Zawsze możesz zastąpić "Self" rzeczywistą nazwą klasy – bjtitus

+0

Dodałem przykład :). – Rengers

Odpowiedz

19

Najbardziej irytujący paradoks w Swift to: "Swift preferuje metody, ale funkcje Swifta są potężniejsze." Zespół Swift wie o tym i pewnego dnia jestem pewien, że będziemy dysponować potężnymi metodami. Ale dzisiaj nie jest ten dzień. Jest wiele rzeczy, które chciałbyś wyrazić w metodach, których nie możesz. Wszystko, co chcesz, można jednak łatwo wykonać za pomocą funkcji.

class ChristmasPresent {} 

struct WrappedPresent<T: ChristmasPresent> { 
    let present: T 
} 

func wrap<T:ChristmasPresent>(present: T) -> WrappedPresent<T> { 
    return WrappedPresent(present: present); 
} 

class ToyCar: ChristmasPresent {} 

let wrappedToyCar = wrap(ToyCar()) // Inferred to be: WrappedPresent<ToyCar> 

Zauważ, że jeśli kod zrobił kompilacji, może nadal być bardzo zaskoczony wynikiem. Swift custom types are not covariant, więc WrappedPresent<ToyCar> nie jest podtypem WrappedPresent<ChristmasPresent>. Więc jeśli masz zestaw zapakowanych prezentów, nie możesz umieścić w nim zawiniętego toycara. To może z łatwością zmusić cię do ponownego użycia stałego typu (nie sparametryzowanego) typem WrappedPresent, co sprawia, że ​​pytanie jest dyskusyjne. Generics i klasy nie zawsze mieszają się tak dobrze, jak można to sobie wyobrazić w Swift.

Jeśli masz praktyczny przykład problemu, który chcesz rozwiązać, zalecam jego wprowadzenie na forach deweloperów. Zespół Swift reaguje bardzo szybko.

+1

Ah oczywiście nigdy nie przyszło mi do głowy, że można to rozwiązać za pomocą funkcji! Nadal myślę zbytnio w myśleniu w Objective-C :). – Rengers