web-dev-qa-db-fra.com

Que sont 'get' et 'set' dans Swift?

J'apprends Swift et je lis The Swift Programming Language d'Apple, je n'ai pas de connaissances en Objective C (seulement PHP, JS et autre mais pas 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 en comprendre le sens.

Quelqu'un peut-il m'expliquer ce que get et set sont?

89
Mr.Web

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

Outre les propriétés simples 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 fait ceci:

let someVar = myTriangle.perimeter

... Qui appelle ceci:

get{
    return 3.0 * self.sideLength
}

Et c'est donc 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

Qui appelle le code dans le bloc set{}:

set {
    sideLength = newValue / 3.0
}

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

myTriangle.sideLength = 100/3.0

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

Dans Swift, nous pouvons avoir des propriétés calculées une fois obtenues et pouvant faire quelque chose lorsqu'elles sont définies. Nous pourrions aussi faire cela 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;
}
31
Undo

L'obtention et la définition de variables au sein de classes fait référence à la récupération ("obtention") ou à la modification ("paramétrage") de leur contenu.

Considérons une variable members d'une classe family. Naturellement, cette variable devrait être un entier, puisqu’une famille ne peut jamais être composée de deux personnes.

Donc, vous iriez probablement de l'avant en définissant la variable members comme ceci:

class family {
   var members:Int
}

Cependant, cela donnera aux utilisateurs de cette classe la possibilité de définir le nombre de membres de la famille à 0 ou 1. Et comme il n’existe pas de famille à 1 ou 0, c’est bien dommage.

C’est là que les accesseurs et les préposés entrent en jeu. Ainsi, vous pouvez décider vous-même de la façon dont les variables peuvent être modifiées et des valeurs qu’elles peuvent recevoir, ainsi que du contenu qu’elles renverront.

De retour dans notre classe familiale, assurons-nous que personne ne puisse définir la valeur members sur une valeur inférieure à 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 variable members comme auparavant, en tapant instanceOfFamily.members, et grâce à la fonction setter, nous pouvons également définir sa valeur comme auparavant, en tapant, par exemple: instanceOfFamily.members = 3. Cependant, ce qui a changé, c’est que nous ne pouvons plus définir cette variable sur une valeur inférieure à 2.

Notez l'introduction de la variable _members, qui est la variable réelle pour stocker la valeur que nous avons définie via la fonction members setter. La members originale est maintenant devenue une propriété calculée, ce qui signifie qu’elle n’agit que comme une interface permettant de traiter notre variable réelle.

102
Markus Buhl

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

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

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

PS Lorsque vous définissez 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 partie set{} 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
16
Maxim

Vous devriez regarder Propriétés calculées

Dans votre exemple de code, perimeter est une propriété non sauvegardée par une variable de classe. Sa valeur est calculée à l'aide de la méthode get et stockée via la méthode set, généralement appelée getter et setter .

Lorsque vous utilisez cette propriété comme ceci:

var cp = myClass.perimeter

vous appelez le code contenu dans le bloc de code get, et lorsque vous l'utilisez comme ceci:

myClass.perimeter = 5.0

vous appelez le code contenu dans le bloc de code set, où newValue est automatiquement renseigné avec la valeur indiquée à droite de l'opérateur d'affectation.

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

1
Antonio