Was sind 'get' und 'set' in Swift?

101

Ich lerne Swift und lese The Swift Programming Languagevon Apple. Ich habe keinen Objective C-Hintergrund (nur PHP, JS und andere, aber kein Obj C).

Auf Seite 24-25 sehe ich diesen Code:

//...Class definition stuff...

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

//...Class continues...

Dieser Teil ist NICHT im Buch angegeben und ich kann nicht verstehen, wofür diese sind.

Kann mir jemand erklären, was bekommen und setzen sind?

Mr.Web
quelle
2
Haben Sie S. 21 über Getter / Setter gelesen? Die ersten 30 Seiten sind eine Tour durch Swift und nicht die vollständige Dokumentation.
Vol7ron
Wenn Sie C ++ gemacht haben, können Sie dieses Zeug mit Getter- und Setter-Mitgliedsfunktionen der Klasse
AbhimanyuAryan

Antworten:

38

Das wird tatsächlich direkt vor dem Code erklärt:

Zusätzlich zu einfachen Eigenschaften, die gespeichert werden, können Eigenschaften einen Getter und einen Setter haben.

class EquilateralTriangle: NamedShape {
    ...

Wenn eine andere Klasse diese Perimetervariable erhalten möchte, tun sie Folgendes:

let someVar = myTriangle.perimeter

... was das nennt:

get{
    return 3.0 * self.sideLength
}

Und so ist es im Wesentlichen so, als ob der aufrufende Controller dies getan hätte:

let someVar = 3.0 * myTriangle.sideLength

Wenn Sie die Variable von einem anderen Objekt aus festlegen , sieht dies folgendermaßen aus:

myTriangle.perimeter = 100

Welches ruft den Code im set{}Block auf:

set {
    sideLength = newValue / 3.0
}

Und so ist es, als hätte die Klasse, die die Variable setzt, Folgendes getan:

myTriangle.sideLength = 100/3.0

Es ist wirklich nur der Einfachheit halber - Sie können dies aus einem anderen Code aufrufen, ohne ständig durch 3 dividieren oder multiplizieren zu müssen, da dies unmittelbar vor dem Festlegen der Variablen und unmittelbar vor dem Abrufen der Variablen erfolgt.

In Swift können wir Eigenschaften haben, die beim Abrufen berechnet werden und beim Festlegen etwas tun können. Wir könnten dies auch in Ziel-C tun:

// .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;
}
Rückgängig machen
quelle
108

Das Abrufen und Setzen von Variablen innerhalb von Klassen bezieht sich entweder auf das Abrufen ("Abrufen") oder das Ändern ("Setzen") ihres Inhalts.

Betrachten Sie eine Variable memberseiner Klasse family. Natürlich müsste diese Variable eine ganze Zahl sein, da eine Familie niemals aus zwei Punkten bestehen kann.

Sie würden also wahrscheinlich fortfahren, indem Sie die membersVariable folgendermaßen definieren :

class family {
   var members:Int
}

Dies gibt jedoch Personen, die diese Klasse verwenden, die Möglichkeit, die Anzahl der Familienmitglieder auf 0 oder 1 zu setzen. Und da es keine Familie mit 1 oder 0 gibt, ist dies ziemlich unglücklich.

Hier kommen die Getter und Setter ins Spiel. Auf diese Weise können Sie selbst entscheiden, wie Variablen geändert werden können und welche Werte sie erhalten können und welche Inhalte sie zurückgeben.

Wenn wir zu unserer Familienklasse zurückkehren, stellen wir sicher, dass niemand den membersWert auf weniger als 2 setzen kann:

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')
     }
   }
  }
}

Jetzt können wir memberswie zuvor auf die Variable zugreifen , indem wir sie eingeben instanceOfFamily.members, und dank der Setter-Funktion können wir ihren Wert auch wie zuvor festlegen, indem wir beispielsweise Folgendes eingeben : instanceOfFamily.members = 3. Was sich jedoch geändert hat, ist die Tatsache, dass wir diese Variable nicht mehr auf etwas kleiner als 2 setzen können.

Beachten Sie die Einführung der _membersVariablen, bei der es sich um die tatsächliche Variable handelt, mit der der Wert gespeichert wird, den wir über die membersSetter-Funktion festgelegt haben. Das Original membersist jetzt eine berechnete Eigenschaft, was bedeutet, dass es nur als Schnittstelle für die Behandlung unserer tatsächlichen Variablen fungiert.

Markus Buhl
quelle
members==> count, numberOfMembers; var members : Set<Person>??
GoZoner
1
set (newVal) { ... }, newVal ist impliziert, also set { _members = newVal }auch richtig.
AndreasHassing
4
Beachten Sie, dass Variablen wie _membersprivat sein sollte, sonst wird der Befehl instanceOfFamily._members=1gesetzt würde instanceOfFamily.membersauf einen Wert unter 2
Daniel
Es sieht so aus, als ob der Standardparameter newValuein Swift 4 - docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Nolan Amy
18

Auf eine einfache Frage sollte eine kurze, einfache und klare Antwort folgen.

  • Wenn wir einen Wert der Immobilie erhalten, feuert sie ihren get{}Teil ab.

  • Wenn wir einen Wert für die Eigenschaft festlegen, wird ihr set{}Teil ausgelöst .

PS. Wenn Sie einen Wert für die Eigenschaft festlegen, erstellt SWIFT automatisch eine Konstante mit dem Namen "newValue" = ein Wert, den wir festlegen. Nach einer Konstante wird "newValue" im set{}Teil der Eigenschaft zugänglich .

Beispiel:

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
quelle
1
Ist es obligatorisch, einen Standardwert für das Mitglied zuzuweisen, auf das von außerhalb der Klasse zugegriffen werden soll? Ich hatte dieses Problem als behoben, als ich Standardwert für die Klasse UserBean: NSObject {var user_id: String? = nil} Zugriff wie folgt let user: UserBean = UserBean () user.user_id = "23232332"
Amr Angry
1

Sie sollten sich die berechneten Eigenschaften ansehen

In Ihrem Codebeispiel perimeterist eine Eigenschaft nicht durch eine Klassenvariable gesichert, sondern ihr Wert wird mithilfe der getMethode berechnet und über die setMethode gespeichert - normalerweise als Getter und Setter bezeichnet .

Wenn Sie diese Eigenschaft wie folgt verwenden:

var cp = myClass.perimeter

Sie rufen den im getCodeblock enthaltenen Code auf und wenn Sie ihn folgendermaßen verwenden:

myClass.perimeter = 5.0

Sie rufen den im setCodeblock enthaltenen Code auf, der newValueautomatisch mit dem rechts vom Zuweisungsoperator angegebenen Wert gefüllt wird.

Berechnete Eigenschaften können schreibgeschützt werden, wenn sowohl ein Getter als auch ein Setter angegeben sind, oder schreibgeschützt, wenn nur der Getter angegeben ist.

Antonio
quelle
0

Variable deklariert und ruft so in einer Klasse auf

class X {
    var x: Int = 3

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

//value of x is:  3

Jetzt möchten Sie programmieren, um den Standardwert von x größer oder gleich 3 zu machen. Nehmen Sie nun den hypothetischen Fall, wenn x kleiner als 3 ist, schlägt Ihr Programm fehl. Sie möchten also, dass die Leute entweder 3 oder mehr als 3 setzen. Swift hat es Ihnen leicht gemacht, und es ist wichtig, diese etwas fortgeschrittene Art der Datierung des Variablenwerts zu verstehen, da sie in der iOS-Entwicklung ausgiebig verwendet werden. Nun wollen wir sehen, wie get und set hier verwendet werden.

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

Wenn Sie immer noch Zweifel haben, denken Sie daran, dass get und set dazu dient, jede Variable so zu aktualisieren, wie wir es möchten. get and set gibt Ihnen eine bessere Kontrolle, um Ihre Logik zu regieren. Leistungsstarkes Werkzeug daher nicht leicht verständlich.

Saran
quelle