Que signifient «get» et «set» dans Swift?

102

J'apprends Swift et je lis The Swift Programming Language d'Apple, je n'ai pas de formation en Objective C (seulement PHP, JS et autres mais pas d'Obj C)

À la page 24-25, je vois ce code:

//...Class definition stuff...

var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
}

//...Class continues...

Cette partie n'est PAS spécifiée dans le livre et je ne peux pas savoir à quoi cela sert.

Quelqu'un peut-il m'expliquer ce que sont les réglages et les réglages ?

Monsieur Web
la source
2
Avez-vous lu la page 21 à propos de getter / setter. De plus, les 30 premières pages environ sont une visite de Swift et non la documentation complète.
vol7ron du
Si vous avez fait du C ++, vous pouvez co-relier ces choses avec les fonctions membres getter et setter de la classe
CodingOnSteroid

Réponses:

38

C'est en fait expliqué juste avant le code:

En plus des propriétés simples qui sont stockées, les propriétés peuvent avoir un getter et un setter.

class EquilateralTriangle: NamedShape {
    ...

Quand une autre classe veut obtenir cette variable de périmètre, elle le fait:

let someVar = myTriangle.perimeter

... qui appelle ceci:

get{
    return 3.0 * self.sideLength
}

Et donc c'est essentiellement comme si le contrôleur appelant faisait ceci:

let someVar = 3.0 * myTriangle.sideLength

Lorsque vous définissez la variable à partir d'un autre objet, cela ressemble à ceci:

myTriangle.perimeter = 100

Ce qui appelle le code dans le set{}bloc:

set {
    sideLength = newValue / 3.0
}

Et c'est comme si la classe qui définit la variable avait fait ceci:

myTriangle.sideLength = 100/3.0

C'est vraiment juste pour la commodité - vous pouvez appeler cela à partir d'un autre code sans avoir à diviser ou multiplier par 3 tout le temps, car cela est fait juste avant de définir la variable et juste avant d'obtenir la variable.

Dans Swift, nous pouvons avoir des propriétés qui sont calculées une fois obtenues et peuvent faire quelque chose lorsqu'elles sont définies. Nous pourrions également le faire en Objective-C:

// .h
@property (nonatomic) double perimeter;

//.m

- (double)perimeter
{
    return self.sideLength * 3.0;
}
- (void)setPerimeter:(double)perimeter
{
    self.perimeter = perimeter; // In Swift, this is done automatically.
    self.sideLength = perimeter / 3.0;
}
Annuler
la source
108

L'obtention et la configuration des variables dans les classes se réfèrent soit à la récupération ("obtention"), soit à la modification ("réglage") de leur contenu.

Considérez une variable membersd'une classe family. Naturellement, cette variable devrait être un entier, car une famille ne peut jamais se composer de deux points quelque chose de personnes.

Donc, vous irez probablement de l'avant en définissant la membersvariable comme ceci:

class family {
   var members:Int
}

Ceci, cependant, donnera aux personnes utilisant cette classe la possibilité de fixer le nombre de membres de la famille à quelque chose comme 0 ou 1. Et comme il n'y a pas de famille de 1 ou 0, c'est assez malheureux.

C'est là que les getters et les setters entrent en jeu. De cette façon, vous pouvez décider vous-même comment les variables peuvent être modifiées et quelles valeurs elles peuvent recevoir, ainsi que décider du contenu qu'elles renvoient.

Revenant à notre classe familiale, assurons-nous que personne ne peut définir la membersvaleur à moins de 2:

class family {
  var _members:Int = 2
  var members:Int {
   get {
     return _members
   }
   set (newVal) {
     if newVal >= 2 {
       _members = newVal
     } else {
       println('error: cannot have family with less than 2 members')
     }
   }
  }
}

Maintenant , nous pouvons accéder à la membersvariable avant, en tapant instanceOfFamily.members, et grâce à la fonction setter, on peut également définir la valeur de comme avant, en tapant, par exemple: instanceOfFamily.members = 3. Ce qui a changé, cependant, c'est le fait que nous ne pouvons plus définir cette variable sur une valeur inférieure à 2.

Notez l'introduction de la _membersvariable, qui est la variable réelle pour stocker la valeur que nous avons définie via la membersfonction setter. L'original membersest maintenant devenu une propriété calculée, ce qui signifie qu'il agit uniquement comme une interface pour traiter notre variable réelle.

Markus Buhl
la source
members==> count, numberOfMembers; var members : Set<Person>??
GoZoner du
1
set (newVal) { ... }, newVal est implicite, il set { _members = newVal }est donc également correct.
AndreasHassing le
4
Notez que les variables comme _membersdevraient être privées, sinon la commande instanceOfFamily._members=1serait définie instanceOfFamily.memberssur une valeur inférieure à 2
Daniel
On dirait que le paramètre par défaut est nommé newValuedans Swift 4 - docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Nolan Amy
19

Une question simple doit être suivie d'une réponse courte, simple et claire.

  • Lorsque nous obtenons une valeur de la propriété, elle déclenche sa get{}part.

  • Lorsque nous définissons une valeur pour la propriété, il déclenche sa set{}partie.

PS. Lors de la définition d'une valeur pour la propriété, SWIFT crée automatiquement une constante nommée "newValue" = une valeur que nous définissons. Après une constante "newValue" devient accessible dans la set{}partie de la propriété .

Exemple:

var A:Int = 0
var B:Int = 0

var C:Int {
get {return 1}
set {print("Recived new value", newValue, " and stored into 'B' ")
     B = newValue
     }
}

//When we are getting a value of C it fires get{} part of C property
A = C 
A            //Now A = 1

//When we are setting a value to C it fires set{} part of C property
C = 2
B            //Now B = 2
Maxime
la source
1
est-il obligatoire d'attribuer une valeur par défaut pour que le membre accède depuis l'extérieur de la classe. J'ai eu ce problème comme résolu lorsque j'attribue une valeur par défaut pour la classe UserBean: NSObject {var user_id: String? = nil} y accéder comme suit let user: UserBean = UserBean () user.user_id = "23232332"
Amr Angry
2

Tu devrais regarder propriétés calculées

Dans votre exemple de code, perimeterest une propriété non sauvegardée par une variable de classe, mais sa valeur est calculée à l'aide de la getméthode et stockée via la setméthode - généralement appelée getter et setter .

Lorsque vous utilisez cette propriété comme ceci:

var cp = myClass.perimeter

vous invoquez le code contenu dans le getbloc de code, et lorsque vous l'utilisez comme ceci:

myClass.perimeter = 5.0

vous invoquez le code contenu dans le setbloc de code, oùnewValue est automatiquement rempli avec la valeur fournie à droite de l'opérateur d'affectation.

Les propriétés calculées peuvent être en lecture-écriture si un getter et un setter sont spécifiés, ou en lecture seule si le getter seul est spécifié.

Antonio
la source
0

variable déclare et appelle comme ceci dans une classe

class X {
    var x: Int = 3

}
var y = X()
print("value of x is: ", y.x)

//value of x is:  3

maintenant vous voulez programmer pour rendre la valeur par défaut de x supérieure ou égale à 3. Maintenant, prenez le cas hypothétique si x est inférieur à 3, votre programme échouera. Donc, vous voulez que les gens mettent 3 ou plus de 3. Swift vous a simplifié la tâche et il est important de comprendre cette façon peu avancée de dater la valeur de la variable car ils l'utiliseront largement dans le développement iOS. Voyons maintenant comment get et set seront utilisés ici.

class X {
    var _x: Int = 3
    var x: Int {
        get {
            return _x
        }
        set(newVal) {  //set always take 1 argument
            if newVal >= 3 {
             _x = newVal //updating _x with the input value by the user
            print("new value is: ", _x)
            }
            else {
                print("error must be greater than 3")
            }
        }
    }
}
let y = X()
y.x = 1
print(y.x) //error must be greater than 3
y.x = 8 // //new value is: 8

si vous avez encore des doutes, rappelez-vous simplement que l'utilisation de get et set consiste à mettre à jour n'importe quelle variable de la manière dont nous voulons qu'elle soit mise à jour. get and set vous donnera un meilleur contrôle pour gouverner votre logique. Outil puissant donc pas facilement compréhensible.

saran
la source