2015-12-20 7 views
35

Ho dei dubbi sui protocolli in Swift sull'uso di var e sulle parole chiave {get set}.Perché non posso usare il protocollo let in Swift?

Da Apple documentation:

Se un protocollo richiede una proprietà di essere ottenibile e impostabile, che requisito proprietà non può essere soddisfatta da una struttura costante memorizzato o una proprietà calcolata di sola lettura. Se il protocollo richiede solo una proprietà , il requisito può essere soddisfatto da qualsiasi tipo di proprietà ed è valido anche per la proprietà che può essere impostata anche se è utile per il proprio codice.

I requisiti di proprietà sono sempre dichiarati come proprietà variabili, preceduti dalla parola chiave var. Le proprietà selezionabili e impostabili sono indicate dalla scrittura {get set} dopo la loro dichiarazione di tipo e le proprietà ottenibili da vengono indicate scrivendo {get}.

non riesco a capire il motivo per cui non posso usare diamo. A var in un protocollo con solo get non è solo un let?

Qualcosa di simile a questo:

protocol someProtocol 
{ 
    var someProperty: String { get } 
} 

non sarebbe solo:

protocol someProtocol 
{ 
    let someProperty: String 
} 

mi manca qualcosa?

+4

una proprietà gettable può ancora modificare i valori - l'implementatore del protocollo può sempre restituire valori diversi, il chiamante del protocollo non può semplicemente impostarli. lascia, d'altra parte, definisce una costante. può essere impostato solo una volta e non può avere un valore diverso. – pvg

+1

@pvg, perché non hai postato questo come risposta? – courteouselk

+0

sì, questa è la risposta corretta qui. – sunshinejr

risposta

35

"Un var in un protocollo con solo get non è solo un let?" No. A let indica una costante. Ma non è questo il caso. Si consideri il seguente:

protocol SomeProtocol { 
    var someProperty: String { get } 
} 

class SomeClass : SomeProtocol { 

    var someProperty: String = "" 

    func cla() { 
     someProperty = "asd" 
    } 
} 

let someInstance = SomeClass() 

print(someInstance.someProperty) // outputs "" 
someInstance.cla() 
print(someInstance.someProperty) // outputs "asd" 

Il protocollo specifica ciò che la classe conforme mostra verso l'esterno - alcune proprietà di tipo String chiamato someProperty quale è possibile almeno get.

Se il protocollo specifica { get }, la classe può scegliere di conformarsi tramite let someProperty: String = "" ma può analogamente scegliere di conformarsi tramite il codice precedente. Se d'altra parte il protocollo specifica { get set } non è possibile utilizzare let nell'implementazione, ma è necessario renderlo impostabile anche.

Un protocollo semplicemente non può definire che un valore deve essere costante - né dovrebbe, cioè un dettaglio di implementazione che deve essere preso in considerazione (o deciso) dalla classe/struttura che lo implementa.

+0

Guardando indietro era così semplice e ovvio, nei protocolli sono permesse solo funzioni (quindi proprietà) ma preferisco sempre chiedere e risolvere ogni dubbio; ora l'uso di '{get set}' è chiaro come sempre, grazie ancora! –

21

La differenza è tra

protocol MyProtocol { 
    let someProperty: String 
} 

che non ha senso - un protocollo non dovrebbe dettare comesomeProperty è definito/memorizzati, solo che è disponibile come una proprietà. Potrebbe essere una proprietà calcolata o archiviata, ma è compito dell'installatore decidere, non del protocollo stesso.

e

protocol MyProtocol { 
    var someProperty: String { get } // abstract interface 
} 

struct MyStruct: MyProtocol { 
    let someProperty: String // concrete implementation: stored property 
} 

struct OtherStruct: MyProtocol { 
    let i: Int 
    var someProperty: String { return "\(i)" } // concrete implementation: computed property 
} 

che è perfettamente consentito!