web-dev-qa-db-fra.com

Pourquoi je ne peux pas utiliser le protocole let in dans Swift?

J'ai un doute sur les protocoles dans Swift sur l'utilisation de var et le mots clés {get set} .

De documentation Apple :

Si un protocole requiert qu'une propriété soit gettable et définissable, cette exigence de propriété ne peut pas être remplie par une propriété stockée constante ou une propriété calculée en lecture seule. Si le protocole requiert uniquement qu'une propriété soit gettable, l'exigence peut être satisfaite par n'importe quel type de propriété, et il est valide que la propriété soit également paramétrable si cela est utile pour votre propre code.

Les exigences en matière de propriétés sont toujours déclarées en tant que propriétés variables, précédées du mot-clé var. Les propriétés getting et settable sont indiquées en écrivant {get set} après leur déclaration de type, et les propriétés gettable sont indiquées en écrivant {get}.

Je ne comprends pas pourquoi je ne peux pas utiliser let . Un var dans un protocole avec seulement get n'est pas seulement un laissez ?

Quelque chose comme ça:

protocol someProtocol 
{
   var someProperty: String { get }
}

ce ne serait pas seulement:

protocol someProtocol 
{
   let someProperty: String
}

Il me manque quelque chose?

59
Massimo Polimeni

"Un var dans un protocole avec seulement get n'est pas seulement un let?" Non. Un let indique une constante. Mais ce n'est pas le cas ici. Considérer ce qui suit:

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"

Le protocole spécifie ce que la classe conforme montre à l'extérieur - une propriété de type String nommée someProperty que vous pouvez au moins obtenir.

Si le protocole spécifie { get } votre classe peut choisir de se conformer via let someProperty: String = "" mais il peut également choisir de se conformer via le code ci-dessus. Si par contre le protocole spécifie { get set } vous ne pouvez pas utiliser let dans l'implémentation mais vous devez également la rendre paramétrable.

Un protocole ne peut tout simplement pas définir qu'une valeur doit être constante - ce ne devrait pas non plus, c'est un détail d'implémentation qui doit être pris en compte (ou décidé) par la classe/structure qui l'implémente.

54
luk2302

La différence est entre

protocol MyProtocol {
    let someProperty: String
}

ce qui n'a aucun sens - un protocole n'est pas censé dicter commentsomeProperty est défini/stocké, seulement that il est disponible en tant que propriété. Il peut s'agir d'une propriété calculée ou stockée, mais c'est à l'implémenteur de décider, pas au protocole lui-même.

et

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
}

ce qui est parfaitement permis!

36
jtbandes