2014-12-16 12 views
9

Self può essere utilizzato come il tipo di ritorno di un metodo:Usa Sé come tipo generico

func doSomething() -> Self {} 

E 'in qualche modo possibile utilizzare Self come un tipo generico come questo?

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

Esempio

Sarebbe bello se potessi sottoclasse ChristmasPresent e lasciare che hanno una funzione che restituisce un wrapped WrappedPresent con il generico insieme a tutto ciò che la sottoclasse era.

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

Cosa rappresenterebbe questo vincolo? Dove è registrato questo vincolo generico? Come viene dichiarato Wrapper? Se è 'Wrapper ', possiamo restituire 'Wrapper ', forse .. – cmyr

+0

C'è una ragione per cui non conosci il tipo di "Sé" al momento? Forse non sto pensando abbastanza bene. È sempre possibile sostituire "Self" con il nome effettivo della classe – bjtitus

+0

Ho aggiunto un esempio :). – Rengers

risposta

19

Il paradosso più fastidioso a Swift è questa: "Swift preferisce metodi, ma le funzioni di Swift sono più potenti." Il team Swift lo sa, e un giorno sono certo che avremo metodi potenti. Ma oggi non è quel giorno. Ci sono molte cose che vorresti esprimere in metodi che non puoi. Tutto ciò che vuoi può essere fatto facilmente con le funzioni, tuttavia.

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> 

Nota che se il codice ha fatto di compilazione, si potrebbe ancora essere molto sorpresi del risultato. Swift custom types are not covariant, quindi un WrappedPresent<ToyCar> non è un sottotipo di WrappedPresent<ChristmasPresent>. Quindi se tu avessi una serie di regali avvolti, non potresti mettere una macchinina avvolta in essa. Ciò potrebbe facilmente costringerti a utilizzare solo un tipo fisso (non parametrizzato) WrappedPresent, rendendo la domanda discutibile. Generici e classi non sempre si mescolano bene come si potrebbe immaginare in Swift.

Se si dispone di un esempio pratico di un problema che si desidera risolvere con questo, quindi mi consiglia di portarlo nei forum dev. Il team di Swift è molto reattivo.

+1

Ah, certo, non mi è mai passato per la testa che fosse risolvibile con le funzioni! Ancora pensando troppo a una mentalità Objective-C :). – Rengers

Problemi correlati