2014-07-21 12 views
7

Aggiornamento: Swift 3 consente di utilizzare Self da altri tipi, grazie a SE-0068 – Expanding Swift Self to class members and value types.'Self' è disponibile solo in un protocollo o come risultato di un metodo di classe

È possibile tornare "Self" da una funzione di classe:

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

modo da poter fare:

let set : NSCountedSet = NSCountedSet.makeOne() 

Tuttavia, i seguenti due non si compilano:

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

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

L'errore è:

<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 

Qualcuno sa di un modo per dichiarare che una funzione di classe restituisce più istanze della classe stessa?

+0

Da segnalare che non c'è alcuna vera ragione per cui questo non dovrebbe essere possibile - sotto il cofano, per un dato 'statica() -> Metodo Self' su un determinato tipo' T', il compilatore genera semplicemente una funzione '(T.Type) -> T'. Quando viene chiamato, il chiamante lancia il risultato sul tipo effettivo sul quale viene chiamato il metodo. Il compilatore è in grado di eseguire la conversione di un array di istanze di sottoclassi in una matrice di istanze di superclasse e una conversione di tuple potrebbe essere banalmente eseguita dalla scomposizione. Quindi, mentre tecnicamente qualcosa che il compilatore * potrebbe * fare, semplicemente non lo supporta (ancora). – Hamish

risposta

4

Il problema, sospetto, è che il Sé è ambiguo; significa "questa classe o una sottoclasse, qualunque cosa sia la nel momento in cui siamo chiamati". In altre parole, il Sé è polimorfico. Ad esempio, non è possibile creare una matrice composta da due classi diverse. E sebbene la classe possa permettere un certo inizializzatore, non possiamo sapere in anticipo che la sua sottoclasse lo farà.

La soluzione è utilizzare il nome classe stesso. Ecco un esempio di cosa struct:

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

Posso capire l'esempio di 'Array', ma perché non permette una' tupla'? –

+0

@LuisAscorbe Non sei sicuro di cosa stai chiedendo. Si noti che questo era da luglio 2014! La lingua Swift è cambiata notevolmente da allora. Se hai una nuova domanda riguardo a come stanno le cose ora, dovresti porla come una nuova domanda. – matt

+0

@matt eventuali modifiche a questo? Mi piacerebbe restituire '[Self]' da un'estensione (su NSObject) ... [nota che ho provato a fare di nuovo la domanda ma sono stato chiuso come un duplicato: stackoverflow.com/questions/43400022] ... grazie ! –

Problemi correlati