Swift Protocole d'obtenir seulement réglable?
pourquoi ne puis-je le faire sans aucune erreur:
var testDto = ModelDto(modelId: 1)
testDto.objectId = 2
alors que j'définir ce:
protocol DataTransferObject {
var objectType: DtoType { get }
var parentObjectId: Int { get set }
var objectId: Int { get }
var objectName: String { get set }
}
struct ModelDto: DataTransferObject {
var objectType: DtoType
var parentObjectId: Int
var objectId: Int
var objectName: String
init(modelId: Int) {
self.objectType = DtoType.Model
self.objectId = modelId
self.parentObjectId = -1
self.objectName = String()
}
}
Si la définition dans mon protocole est la plupart du temps ignorés (getter, setter définition), pourquoi devrais-je les utiliser de toute façon?
- vous avez manqué quelque chose de très important ici. votre protocole n'est pas envisagée, car vous n'êtes pas référence. vous pouvez choisir de consulter ModelDto directement et non via DataTransferObject. Voir ma réponse ci-dessous.
Vous devez vous connecter pour publier un commentaire.
Que par la la documentation officielle:
Les getter et setter exigences peuvent être satisfaites par une conformation de type dans une variété de façons. Si une déclaration de la propriété comprend de l'obtenir et de définir des mots clés, une conformation de type peut la mettre en œuvre avec un stockées propriété de variable ou d'une propriété calculée qui est à la fois lisible et inscriptible (qui est, celui qui implémente à la fois un getter et un setter). Toutefois, cette déclaration de la propriété ne peut pas être mis en œuvre comme une propriété de la constante ou en lecture seule propriété calculée. Si une déclaration de propriété inclut uniquement les obtenir mot-clé, il peut être mis en œuvre comme une sorte de propriété.
ModelDto
n'ont soit getter et setter pourobjectId
. Il est conforme àDataTransferObject
protocole, par le fait d'avoir de la lecture, mais aussi longtemps que vous utilisezModelDto
directement, il a un setter exposés. Vous êtes donc libre de l'appeler. Si vous avez souhaité que votre setter cachés, vous pourriez lancerModelDto
àDataTransferObject
set
, les restrictions sont appliquées à la mise en conformité des types. Je recommande fortement que vous voyez les Imanou réponse ci-dessous. C'est génialApple états dans le "Swift Langage De Programmation (Swift 3)":
Pour cette raison, les cinq suivants, aire de Jeux extraits de code sont toutes valides:
Exemple #1: propriété de la constante
Exemple #2: propriété de variable
Exemple #3: propriété calculée (obtenir uniquement)
Exemple n ° 4: propriété calculée (get et set)
Exemple #5:
private(set)
propriété de variableApple indique également:
Pour cette raison, les deux suivantes de l'aire de Jeux des extraits de code ne SONT PAS valide:
Exemple #1: propriété de la constante
Exemple #2: propriété calculée (obtenir uniquement)
Exemple #3: propriété calculée (obtenir uniquement)
fullName
n'est pas paramétrable à partir d'un niveau de la propriété...l'utilisateur de la classe peut définir directement par l'initialisation.De considérer les éléments suivants:
var testDto = ModelDto(modelId: 1)
La variable
testDto
type ici est connu pour êtreModelDto
.ModelDto
est connu pour avoir une variable mutablevar objectId: Int
. Vous êtes libre de modifier objectId parce que vous êtes accède à l'objet à travers laModelDto
de l'interface et non pas via l'interface de protocole d'où il n'est gettable.Essayez ce qui suit:
L'exemple ci-dessus ne devrait pas compiler. Parce que le type de
testDto
est connu pour êtreDataTransferObject
, nous ne savons pas qui les sous-tendent la mise en œuvre a un réglable propriété. Nous savons seulement sur le gettable bien déclaré dans le protocole.En bref, vous avez déclaré
ModelDto
d'avoir un get/set variable, de sorte qu'il serait assez étrange en effet, si Swift n'a pas vous permettent de le définir. Avoir une seule variable serait compter sur vous referncing l'objet via le protocole ou la modification deobjectId
surModelDTO
être une variable.EDIT: pour répondre À votre confusion au sujet de pourquoi
ModelDto
est autorisé à avoir un réglable variable. C'est la même que la façon dontModelDto
est autorisé à avoir d'autres fonctions que celles définies dans le protocole. Les accesseurs et mutateurs sont en fait que des fonctions, de sorte que le protocole nécessitant un getter ne fait pas obstacle à une mise en œuvre à partir également d'avoir un setter. La même chose est possible en Objective C. Protocoles sont descriptive, n'est pas restrictif.Dans votre classe, vous créez un stockées propriété nommée
objectId
. Dans votre protocole, vous indiquez que la propriété a besoin d'une lecture – c'est sa seule condition.Si vous voulais que ce soit un ordinateur de propriété, comme vous l'attendez, vous avez besoin de déclarer
objectId
avec les éléments suivants:Sans la fermeture de calculer la valeur, il est, par défaut, un stockées propriété.
je vais répondre à la question dans son sens générique.
Avant de répondre à la question que vous devez savoir de quoi
get
&set
veux dire.(Si vous en r'venant de l'Objective-C le monde:)
get
signifie readOnly, c'est que je me suis permis de connaître le nombre de pattes d'un animal. Je ne suis pas autorisé à le définir.get
&set
ensemble des moyens readWrite ie j'ai le droit de connaître le poids d'un animal alors que je suis également en mesure de définir ou de modifier le poids d'un animalAvec l'exemple suivant.
Si vous ne disposez que de lecture, et de tenter de masquer setter (en utilisant
private (set)
... alors vous n'obtiendrez PAS une erreur ... c'est probablement ce que vous voulais et comment cela doit être fait!Probable que ce que vous:
Probablement que vous n'avez pas l'intention:
Essentiellement avec
{get}
il y a encore quelques supplémentaire travail à faire par le compilateur n'est pas vous dire..., VOUS devez ajouterprivate (set)
pour obtenir le comportement vouluSi votre propriété a setter et que vous essayez de cacher setter ensuite, vous voyez une erreur.
Vous n'êtes pas autorisés à se cacher, parce que vous avez promis de fournir un setter...
Le comportement que vous voyez sur votre exemple de code est appelé membre de la clandestinité. Membre de cacher qui se passe dans les langages orientés objets lorsqu'un nouveau membre est déclarée avec le même nom ou la signature d'une maladie héréditaire, donc en ayant:
var objectId: Int
dans votre structure de mise en œuvre, vous êtes effectivement la création d'un nouveau membre appelé objectId et de cacher la propriété héritée par le protocole.
Afin d'honorer le contrat entre votre structure et de votre protocole, objectId pourrait être déclarée comme suit:
ou