2016-06-16 5 views
6

Diciamo che ho la seguente classe Swift semplice:Le definizioni di una classe Swift sono assegnate solo una volta o per istanza?

class Burrito { 
    enum Ingredients { 
     case beans, cheese, lettuce, beef, chicken, chorizo 
    } 

    private let meats : Set<Ingredients> = [.beef, .chicken, .chorizo] 

    var fillings : Set<Ingredients> 

    init (withIngredients: Set<Ingredients>) { 
     fillings = withIngredients 
    } 

    func isVegetarian() -> Bool { 
     if fillings.intersect(meats).count > 0 { 
      return false 
     } 
     else { 
      return true 
     } 
    } 
} 

Se creo più istanze di Burrito in un'applicazione, è l'insieme carni definite in memoria una volta, separati dalla memoria allocata per ogni istanza? Suppongo che il compilatore ottimizzerebbe in questo modo, ma non sono ancora riuscito a trovare una risposta.

EDIT

Con il grande aiuto dalla risposta accettata, e le osservazioni circa la logica nel metodo isVegetarian(), qui è la classe modificata. Grazie a tutti!

class Burrito { 
    enum Ingredients { 
     case beans, cheese, lettuce, beef, chicken, chorizo 
    } 

    private static let meats : Set<Ingredients> = [.beef, .chicken, .chorizo] 

    var fillings : Set<Ingredients> 

    init (withIngredients: Set<Ingredients>) { 
     fillings = withIngredients 
    } 

    func isVegetarian() -> Bool { 
     return fillings.intersect(Burrito.meats).isEmpty 
    } 

    // All burritos are delicious 
    func isDelicious() -> Bool { 
     return true 
    } 
} 
+1

Nota a margine: 'fillings.intersect (carni) .count> 0' è un'espressione che restituisce un' Bool'. Non è necessario avvolgerlo in un 'if' /' else' e ​​manualmente 'return'' true'/'false'. Si può semplicemente usare: 'return! (Fillings.intersect (meat) .count> 0)' – Alexander

+0

Nice catch. L'ho buttato velocemente insieme per provare alcune cose con i test unitari e non pensavo chiaramente. –

+1

@AMomchilov O semplicemente 'return fillings.intersect (meat) .isEmpty';) – Hamish

risposta

3

meats è una variabile di istanza della classe. Una nuova istanza di meats verrà creata per ogni nuova istanza (oggetto) creata dalla classe.

È possibile utilizzare la parola chiave static per trasformarla in una variabile statica, in modo che sia presente una sola istanza della variabile meats, che è condivisa tra tutti i membri della classe.

Le variabili di istanza immutabili vengono in genere utilizzate come costanti a livello di oggetto (anziché a livello di classe, come variabili statiche immutabili), che possono avere definizioni indipendenti per ciascun oggetto. In questo caso, la definizione è statica, quindi un compilatore intelligente potrebbe ottimizzarlo in una variabile statica. Indipendentemente da ciò, è necessario contrassegnare esplicitamente questo static per comunicare agli utenti l'intento di questa variabile.

+0

Ok, stavo ricevendo un errore che "membro statico non può essere utilizzato su istanza di tipo 'Burrito'." Dovrei quindi usare 'static let let meat: Set = [.beef, .chicken, .chorizo]' per la definizione, quindi accedervi con 'Burrito.meats' nelle funzioni? –

+1

Sì, Swift consente di chiamare solo membri statici su tipi, non su istanze. – Alexander

Problemi correlati