Swift-Eigenschaften

Swift-Eigenschaften verknüpfen Werte mit einer bestimmten Klasse, Struktur oder Aufzählung.

Eigenschaften können in gespeicherte Eigenschaften und berechnete Eigenschaften unterteilt werden:

Gespeicherte Eigenschaften Berechnete Eigenschaften
Konstanten oder Variablen als Teil einer Instanz speichern Einen Wert berechnen (anstatt ihn zu speichern)
Wird für Klassen und Strukturen verwendet Wird für Klassen, Strukturen und Aufzählungen verwendet

Gespeicherte und berechnete Eigenschaften werden üblicherweise für Instanzen eines bestimmten Typs verwendet.

Eigenschaften können auch direkt auf dem Typ selbst verwendet werden, und solche Eigenschaften werden als Typ-Eigenschaften bezeichnet.

Darüber hinaus können Sie Eigenschaftsbeobachter definieren, um Änderungen an Eigenschaftswerten zu überwachen und dadurch eine benutzerdefinierte Aktion auszulösen. Eigenschaftsbeobachter können zu gespeicherten Eigenschaften, die Sie schreiben, oder zu Eigenschaften hinzugefügt werden, die von einer Oberklasse geerbt wurden.


Gespeicherte Eigenschaften

Einfach ausgedrückt ist eine gespeicherte Eigenschaft eine Konstante oder Variable, die in einer Instanz einer bestimmten Klasse oder Struktur gespeichert ist.

Gespeicherte Eigenschaften können variable gespeicherte Eigenschaften (definiert mit dem Schlüsselwort `var`) oder konstante gespeicherte Eigenschaften (definiert mit dem Schlüsselwort `let`) sein.

  • Beim Definieren einer gespeicherten Eigenschaft können Sie einen Standardwert angeben.

  • Sie können den Wert einer gespeicherten Eigenschaft auch während der Initialisierung festlegen oder ändern und sogar den Wert einer konstanten gespeicherten Eigenschaft ändern.

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)")

Die Ausgabe des obigen Programms ist:

67
3.1415

Betrachten Sie den folgenden Code:

let pi = 3.1415

Im Code erhält `pi` einen Standardwert, wenn die gespeicherte Eigenschaft definiert wird (`pi = 3.1415`), sodass er sich unabhängig davon, wann Sie die Struktur instanziieren, nicht ändert.

Wenn Sie eine konstante gespeicherte Eigenschaft definieren und versuchen, sie zu ändern, wird ein Fehler gemeldet, wie unten gezeigt:

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

Das obige Programm meldet bei der Ausführung einen Fehler, wie unten gezeigt:

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

Das bedeutet, dass 'numbers' eine Konstante ist und nicht geändert werden kann.


Verzögerte gespeicherte Eigenschaften

Eine verzögerte gespeicherte Eigenschaft ist eine Eigenschaft, deren Anfangswert erst beim ersten Zugriff berechnet wird.

Verwenden Sie vor der Eigenschaftsdeklarationlazy, um eine verzögerte gespeicherte Eigenschaft anzugeben.

Hinweis:
Sie müssen eine verzögerte gespeicherte Eigenschaft als Variable deklarieren (mit demvarSchlüsselwort), weil der Wert der Eigenschaft möglicherweise nicht abgerufen werden kann, bevor die Initialisierung der Instanz abgeschlossen ist. Konstante Eigenschaften müssen vor Abschluss der Initialisierung einen Anfangswert haben, daher können sie nicht als verzögerte Eigenschaften deklariert werden.

Verzögerte gespeicherte Eigenschaften werden in der Regel für Folgendes verwendet:

  • Das Verzögern der Erstellung von Objekten.

  • Wenn der Wert der Eigenschaft von anderen unbekannten Klassen abhängt.

import Cocoa

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

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

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

Die Ausgabe des obigen Programms ist:

Example Swift 教程

Instanzvariablen

Wenn Sie Erfahrung mit Objective-C haben, sollten Sie wissen, dass Objective-C zwei Möglichkeiten bietet, Werte und Referenzen für Klasseninstanzen zu speichern. Bei Eigenschaften können Instanzvariablen auch als zugrunde liegender Speicher für Eigenschaftswerte verwendet werden.

Die Programmiersprache Swift vereinheitlicht diese Theorien mithilfe von Eigenschaften. Eigenschaften in Swift haben keine entsprechende Instanzvariable, und auf den zugrunde liegenden Speicher einer Eigenschaft kann nicht direkt zugegriffen werden. Dies vermeidet die Verwirrung durch unterschiedliche Zugriffsmethoden in verschiedenen Szenarien und vereinfacht außerdem die Definition einer Eigenschaft zu einer einzigen Anweisung.

Alle Informationen über eine Eigenschaft in einem Typ – einschließlich ihres Namens, Typs und ihrer Speicherverwaltungsmerkmale – werden an einer einzigen Stelle definiert (in der Typdefinition).


Berechnete Eigenschaften

Zusätzlich zu gespeicherten Eigenschaften können Klassen, Strukturen und Enumerationenberechnete Eigenschaftendefinieren; berechnete Eigenschaften speichern keinen Wert direkt. Stattdessen bieten sie einen Getter zum Abrufen eines Werts und optional einen Setter, um den Wert anderer Eigenschaften oder Variablen indirekt festzulegen.

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)

Die Ausgabe des obigen Programms ist:

(150.0, 75.0)
-150.0
-65.0

Wenn der Setter einer berechneten Eigenschaft keinen Parameternamen für den neuen Wert definiert, kannst du den Standardnamen `newValue` verwenden.


Schreibgeschützte berechnete Eigenschaften

Eine berechnete Eigenschaft mit nur einem Getter und ohne Setter ist eine schreibgeschützte berechnete Eigenschaft.

Eine schreibgeschützte berechnete Eigenschaft gibt immer einen Wert zurück; auf sie kann mit dem Punktoperator (.) zugegriffen werden, aber sie kann nicht auf einen neuen Wert gesetzt werden.

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"]!)

Die Ausgabe des obigen Programms ist:

Swift 属性
3.09

Hinweis:

Du musstvardas Schlüsselwort zum Definieren berechneter Eigenschaften, einschließlich schreibgeschützter berechneter Eigenschaften, verwenden, weil ihre Werte nicht fest sind.letDas Schlüsselwort wird nur verwendet, um konstante Eigenschaften zu deklarieren, was einen Wert angibt, der nach der Initialisierung nicht geändert werden kann.


Eigenschaftsbeobachter

Eigenschaftsbeobachter überwachen Änderungen am Wert einer Eigenschaft und reagieren darauf. Sie werden jedes Mal aufgerufen, wenn eine Eigenschaft gesetzt wird, selbst wenn der neue Wert mit dem aktuellen Wert übereinstimmt.

Du kannst Eigenschaftsbeobachter zu gespeicherten Eigenschaften, die keine lazy gespeicherten Eigenschaften sind, hinzufügen, und du kannst auch Eigenschaftsbeobachter zu geerbten Eigenschaften (einschließlich gespeicherter und berechneter Eigenschaften) hinzufügen, indem du die Eigenschaft überschreibst.

Hinweis:
Du musst berechneten Eigenschaften, die nicht überschrieben werden können, keine Eigenschaftsbeobachter hinzufügen, da du Wertänderungen direkt über den Setter überwachen und darauf reagieren kannst.

Du kannst einer Eigenschaft einen oder alle der folgenden Beobachter hinzufügen:

  • willSetwird aufgerufen, bevor der neue Wert gesetzt wird
  • didSetwird unmittelbar aufgerufen, nachdem der neue Wert gesetzt wurde
  • Die Beobachter `willSet` und `didSet` werden während der Initialisierung einer Eigenschaft nicht aufgerufen.
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

Die Ausgabe des obigen Programms ist:

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

Globale und lokale Variablen

Die für berechnete Eigenschaften und Eigenschaftsbeobachter beschriebenen Muster können auch für globale und lokale Variablen verwendet werden.

Lokale Variablen Globale Variablen
Variablen, die innerhalb einer Funktion, Methode oder Closure definiert sind. Variablen, die außerhalb von Funktionen, Methoden, Closures oder eines beliebigen Typs definiert sind.
Wird verwendet, um Werte zu speichern und abzurufen. Wird verwendet, um Werte zu speichern und abzurufen.
Gespeicherte Eigenschaften werden zum Abrufen und Setzen von Werten verwendet. Gespeicherte Eigenschaften werden zum Abrufen und Setzen von Werten verwendet.
Wird auch für berechnete Eigenschaften verwendet. Wird auch für berechnete Eigenschaften verwendet.

Typ-Eigenschaften

Typ-Eigenschaften werden als Teil der Typdefinition innerhalb der äußersten geschweiften Klammern ({}) des Typs geschrieben.

Verwenden Sie das Schlüsselwort `static`, um Typ-Eigenschaften für Werttypen zu definieren, und das Schlüsselwort `class`, um Typ-Eigenschaften für Klassen zu definieren.

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 值
   }
}

Hinweis:
Die berechneten Typ-Eigenschaften im Beispiel sind schreibgeschützt, aber Sie können auch lesbare und beschreibbare berechnete Typ-Eigenschaften definieren, ähnlich wie bei der Syntax für berechnete Instanzeigenschaften.


Abrufen und Festlegen von Typ-Eigenschaftswerten

Ähnlich wie bei Instanzeigenschaften erfolgt der Zugriff auf Typ-Eigenschaften mit dem Punktoperator (.). Der Zugriff auf Typ-Eigenschaften und deren Festlegung erfolgen jedoch über den Typ selbst, nicht über eine Instanz. Zum Beispiel:

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)

Die Ausgabe des obigen Programms ist:

97
87
Andere Erweiterungen