Propriétés Swift

Les propriétés Swift associent des valeurs à une classe, une structure ou une énumération particulières.

Les propriétés peuvent être divisées en propriétés stockées et propriétés calculées :

Propriétés stockées Propriétés calculées
Stocker des constantes ou des variables dans le cadre d’une instance Calculer (plutôt que stocker) une valeur
Utilisé pour les classes et les structures Utilisé pour les classes, les structures et les énumérations

Les propriétés stockées et calculées sont généralement utilisées pour des instances d’un type particulier.

Les propriétés peuvent également être utilisées directement sur le type lui-même, et ces propriétés sont appelées propriétés de type.

De plus, vous pouvez définir des observateurs de propriété pour surveiller les modifications des valeurs de propriété, déclenchant ainsi une action personnalisée. Les observateurs de propriété peuvent être ajoutés aux propriétés stockées que vous écrivez, ou aux propriétés héritées d’une superclasse.


Propriétés stockées

En termes simples, une propriété stockée est une constante ou une variable stockée dans une instance d’une classe ou d’une structure particulière.

Les propriétés stockées peuvent être des propriétés stockées variables (définies avec le mot-clé `var`) ou des propriétés stockées constantes (définies avec le mot-clé `let`).

  • Vous pouvez spécifier une valeur par défaut lors de la définition d’une propriété stockée.

  • Vous pouvez également définir ou modifier la valeur d’une propriété stockée lors de l’initialisation, et même modifier la valeur d’une propriété stockée constante.

import Cocoa

struct Number
{
   var digits: Int
   let pi = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.pi)")

La sortie du programme ci-dessus est :

67
3.1415

Considérez le code suivant :

let pi = 3.1415

Dans le code, `pi` reçoit une valeur par défaut lorsque la propriété stockée est définie (`pi = 3.1415`), donc quel que soit le moment où vous instanciez la structure, elle ne changera pas.

Si vous définissez une propriété stockée constante et essayez de la modifier, une erreur sera signalée, comme indiqué ci-dessous :

import Cocoa

struct Number
{
    var digits: Int
    let numbers = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.numbers)")
n.numbers = 8.7

Le programme ci-dessus signalera une erreur lors de son exécution, comme indiqué ci-dessous :

error: cannot assign to property: 'numbers' is a 'let' constant
n.numbers = 8.7

Cela signifie que 'numbers' est une constante et que vous ne pouvez pas la modifier.


Propriétés stockées paresseuses

Une propriété stockée paresseuse est une propriété dont la valeur initiale n'est calculée qu'au premier accès.

Utilisez avant la déclaration de propriétélazypour indiquer une propriété stockée paresseuse.

Remarque :
Vous devez déclarer une propriété stockée paresseuse comme une variable (en utilisant levarmot-clé), car la valeur de la propriété peut ne pas être obtenue avant que l'initialisation de l'instance soit terminée. Les propriétés constantes doivent avoir une valeur initiale avant la fin de l'initialisation, elles ne peuvent donc pas être déclarées comme propriétés paresseuses.

Les propriétés stockées paresseuses sont généralement utilisées pour :

  • Retarder la création d'objets.

  • Lorsque la valeur de la propriété dépend d'autres classes inconnues.

import Cocoa

class sample {
    lazy var no = number() // `var` 关键字是必须的
}

class number {
    var name = "Example Swift 教程"
}

var firstsample = sample()
print(firstsample.no.name)

La sortie du programme ci-dessus est :

Example Swift 教程

Variables d'instance

Si vous avez de l’expérience avec Objective-C, vous devez savoir qu’Objective-C fournit deux façons de stocker des valeurs et des références pour les instances de classe. Pour les propriétés, les variables d’instance peuvent également être utilisées comme stockage sous-jacent des valeurs de propriété.

Le langage de programmation Swift unifie ces concepts à l’aide des propriétés. Les propriétés en Swift n’ont pas de variable d’instance correspondante, et le stockage sous-jacent d’une propriété n’est pas accessible directement. Cela évite la confusion entre différentes méthodes d’accès dans différents scénarios, et simplifie également la définition d’une propriété en une seule instruction.

Toutes les informations concernant une propriété dans un type — y compris son nom, son type et ses caractéristiques de gestion de la mémoire — sont définies à un seul endroit (dans la définition du type).


Propriétés calculées

En plus des propriétés stockées, les classes, les structures et les énumérations peuvent définirdes propriétés calculées; les propriétés calculées ne stockent pas directement une valeur. Au lieu de cela, elles fournissent un getter pour obtenir une valeur et un setter optionnel pour définir indirectement la valeur d’autres propriétés ou variables.

import Cocoa

class sample {
    var no1 = 0.0, no2 = 0.0
    var length = 300.0, breadth = 150.0
    
    var middle: (Double, Double) {
        get{
            return (length / 2, breadth / 2)
        }
        set(axis){
            no1 = axis.0 - (length / 2)
            no2 = axis.1 - (breadth / 2)
        }
    }
}

var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)

print(result.no1)
print(result.no2)

La sortie du programme ci-dessus est :

(150.0, 75.0)
-150.0
-65.0

Si le setter d’une propriété calculée ne définit pas de nom de paramètre pour la nouvelle valeur, vous pouvez utiliser le nom par défaut `newValue`.


Propriétés calculées en lecture seule

Une propriété calculée avec uniquement un getter et sans setter est une propriété calculée en lecture seule.

Une propriété calculée en lecture seule renvoie toujours une valeur ; elle est accessible avec l’opérateur point (.) mais ne peut pas se voir attribuer une nouvelle valeur.

import Cocoa

class film {
    var head = ""
    var duration = 0.0
    var metaInfo: [String:String] {
        return [
            "head": self.head,
            "duration":"\(self.duration)"
        ]
    }
}

var movie = film()
movie.head = "Swift 属性"
movie.duration = 3.09

print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)

La sortie du programme ci-dessus est :

Swift 属性
3.09

Remarque :

Vous devez utiliservarle mot-clé pour définir des propriétés calculées, y compris les propriétés calculées en lecture seule, car leurs valeurs ne sont pas fixes.letLe mot-clé est uniquement utilisé pour déclarer des propriétés constantes, ce qui indique une valeur qui ne peut pas être modifiée après l’initialisation.


Observateurs de propriété

Les observateurs de propriété surveillent les changements de valeur d'une propriété et y réagissent. Ils sont appelés chaque fois qu'une propriété est définie, même lorsque la nouvelle valeur est identique à la valeur actuelle.

Vous pouvez ajouter des observateurs de propriété à des propriétés stockées autres que les propriétés stockées lazy, et vous pouvez également ajouter des observateurs de propriété à des propriétés héritées (y compris les propriétés stockées et calculées) en redéfinissant la propriété.

Remarque :
Vous n'avez pas besoin d'ajouter des observateurs de propriété aux propriétés calculées qui ne peuvent pas être redéfinies, car vous pouvez directement surveiller et réagir aux changements de valeur via le setter.

Vous pouvez ajouter un ou tous les observateurs suivants à une propriété :

  • willSetappelé avant que la nouvelle valeur soit définie
  • didSetappelé immédiatement après que la nouvelle valeur a été définie
  • Les observateurs `willSet` et `didSet` ne sont pas appelés lors de l'initialisation d'une propriété.
import Cocoa

class Samplepgm {
    var counter: Int = 0{
        willSet(newTotal){
            print("计数器: \(newTotal)")
        }
        didSet{
            if counter > oldValue {
                print("新增数 \(counter - oldValue)")
            }
        }
    }
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800

La sortie du programme ci-dessus est :

计数器: 100
新增数 100
计数器: 800
新增数 700

Variables globales et locales

Les modèles décrits pour les propriétés calculées et les observateurs de propriété peuvent également être utilisés pour les variables globales et locales.

Variables locales Variables globales
Variables définies à l'intérieur d'une fonction, d'une méthode ou d'une closure. Variables définies en dehors des fonctions, des méthodes, des closures ou de tout type.
Utilisées pour stocker et récupérer des valeurs. Utilisées pour stocker et récupérer des valeurs.
Les propriétés stockées servent à obtenir et définir des valeurs. Les propriétés stockées servent à obtenir et définir des valeurs.
Également utilisé pour les propriétés calculées. Également utilisé pour les propriétés calculées.

Propriétés de type

Les propriétés de type sont écrites dans le cadre de la définition du type, à l'intérieur des accolades les plus externes ({}) du type.

Utilisez le mot-clé `static` pour définir des propriétés de type pour les types valeur, et le mot-clé `class` pour définir des propriétés de type pour les classes.

struct Structname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
      // 这里返回一个 Int 值
   }
}

enum Enumname {
   static var storedTypeProperty = " "
   static var computedTypeProperty: Int {
      // 这里返回一个 Int 值
   }
}

class Classname {
   class var computedTypeProperty: Int {
      // 这里返回一个 Int 值
   }
}

Remarque :
Les propriétés de type calculées dans l'exemple sont en lecture seule, mais vous pouvez également définir des propriétés de type calculées accessibles en lecture et en écriture, de manière similaire à la syntaxe des propriétés calculées d'instance.


Obtention et définition des valeurs de propriétés de type

Comme pour les propriétés d'instance, les propriétés de type sont accessibles à l'aide de l'opérateur point (.). Cependant, les propriétés de type sont accessibles et définies via le type lui-même, et non via une instance. Par exemple :

import Cocoa

struct StudMarks {
   static let markCount = 97
   static var totalCount = 0
   var InternalMarks: Int = 0 {
      didSet {
         if InternalMarks > StudMarks.markCount {
            InternalMarks = StudMarks.markCount
         }
         if InternalMarks > StudMarks.totalCount {
            StudMarks.totalCount = InternalMarks
         }
      }
   }
}

var stud1Mark1 = StudMarks()
var stud1Mark2 = StudMarks()

stud1Mark1.InternalMarks = 98
print(stud1Mark1.InternalMarks) 

stud1Mark2.InternalMarks = 87
print(stud1Mark2.InternalMarks)

La sortie du programme ci-dessus est :

97
87
Autres extensions