Co to jest „pobierz” i „ustaw” w Swift?

102

Uczę się Swift i czytam The Swift Programming Language od Apple, nie mam tła Objective C (tylko PHP, JS i inne, ale bez Obj C)

Na stronach 24-25 widzę ten kod:

//...Class definition stuff...

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

//...Class continues...

Ta część NIE jest opisana w książce i nie mogę znaleźć tego, do czego służą.

Czy ktoś może mi wyjaśnić, czym są get i set ?

Panie Web
źródło
2
Czy przeczytałeś stronę 21 o getter / setter. Również pierwsze 30 PGS lub tak to wycieczka z Swift, a nie pełna dokumentacja.
vol7ron,
Jeśli zrobiłeś C ++, możesz
kojarzyć

Odpowiedzi:

38

Faktycznie zostało to wyjaśnione tuż przed kodem:

Oprócz przechowywanych prostych właściwości właściwości mogą mieć metodę pobierającą i ustawiającą.

class EquilateralTriangle: NamedShape {
    ...

Gdy inna klasa chce pobrać tę zmienną obwodową, robią to:

let someVar = myTriangle.perimeter

... co nazywa się tym:

get{
    return 3.0 * self.sideLength
}

Zasadniczo wygląda to tak, jakby kontroler wywołujący zrobił to:

let someVar = 3.0 * myTriangle.sideLength

Kiedy ustawiasz zmienną z innego obiektu, wygląda to tak:

myTriangle.perimeter = 100

Który wywołuje kod w set{}bloku:

set {
    sideLength = newValue / 3.0
}

A więc to tak, jakby klasa ustawiająca zmienną zrobiła to:

myTriangle.sideLength = 100/3.0

To naprawdę tylko dla wygody - możesz wywołać to z innego kodu bez konieczności ciągłego dzielenia przez 3 lub mnożenia przez 3, ponieważ robi się to tuż przed ustawieniem zmiennej i tuż przed otrzymaniem zmiennej.

W języku Swift możemy mieć właściwości, które są obliczane podczas pobierania i mogą coś zrobić, gdy są ustawione. Moglibyśmy to zrobić również w 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;
}
Cofnij
źródło
108

Pobieranie i ustawianie zmiennych w ramach klas odnosi się do pobierania („pobierania”) lub zmieniania („ustawiania”) ich zawartości.

Rozważmy zmienną membersklasy family. Oczywiście ta zmienna musiałaby być liczbą całkowitą, ponieważ rodzina nigdy nie może składać się z dwóch punktów, czyli czegoś, co ludzie.

Więc prawdopodobnie poszedłbyś dalej, definiując memberszmienną w następujący sposób:

class family {
   var members:Int
}

To jednak da ludziom używającym tej klasy możliwość ustawienia liczby członków rodziny na około 0 lub 1. A ponieważ nie ma czegoś takiego jak rodzina 1 lub 0, jest to bardzo niefortunne.

Tutaj wkraczają metody pobierające i ustawiające. W ten sposób możesz samodzielnie zdecydować, jak zmienne mogą być zmieniane i jakie wartości mogą one otrzymać, a także zdecydować, jaką zawartość zwracają.

Wracając do naszej klasy rodzinnej, upewnijmy się, że nikt nie może ustawić members wartości mniejszej niż 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')
     }
   }
  }
}

Teraz możemy uzyskać dostęp do members zmiennej, jak poprzednio, przez pisanie instanceOfFamily.members, a dzięki funkcji setter, możemy także ustawić jego wartość jak poprzednio, przez pisanie, na przykład: instanceOfFamily.members = 3. Zmieniło się jednak to, że nie możemy już ustawić tej zmiennej na wartość mniejszą niż 2.

Zwróć uwagę na wprowadzenie _memberszmiennej, która jest rzeczywistą zmienną do przechowywania wartości ustawionej przez funkcję membersustawiającą. Oryginał membersstał się teraz własnością obliczoną, co oznacza, że ​​działa tylko jako interfejs do obsługi naszej rzeczywistej zmiennej.

Markus Buhl
źródło
members==> count, numberOfMembers; var members : Set<Person>??
GoZoner,
1
set (newVal) { ... }, zakłada się newVal, więc set { _members = newVal }jest również poprawne.
AndreasHassing
4
Zwróć uwagę, że zmienne takie jak _memberspowinny być prywatne, w przeciwnym razie polecenie instanceOfFamily._members=1ustawiłoby instanceOfFamily.memberswartość poniżej 2
Daniel
Wygląda na to, że domyślny parametr ma nazwę newValuew Swift 4 - docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Nolan Amy
19

Po prostym pytaniu powinna następować krótka, prosta i jasna odpowiedź.

  • Kiedy uzyskujemy wartość nieruchomości, odpala jej get{}część.

  • Kiedy ustawiamy wartość właściwości, odpala jej set{}część.

PS. Podczas ustawiania wartości właściwości, SWIFT automatycznie tworzy stałą o nazwie „nowaWartość” = ustawiana przez nas wartość. Po tym, jak stała „nowa wartość” staje się dostępna w pliku właściwościset{} .

Przykład:

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
Maksyma
źródło
1
czy obowiązkowe jest przypisanie wartości domyślnej członkowi, aby uzyskać dostęp spoza klasy. problem został rozwiązany, gdy przypisuję mu domyślną wartość klasy UserBean: NSObject {var user_id: String? = nil} uzyskując do niego dostęp w następujący sposób, niech użytkownik: UserBean = UserBean () user.user_id = "23232332"
Amr Angry
2

Powinieneś spojrzeć na obliczone właściwości

W przykładowym kodzie perimeterjest to właściwość, która nie jest zabezpieczona przez zmienną klasy, zamiast tego jej wartość jest obliczana przy użyciu getmetody i przechowywana za pośrednictwem setmetody - zwykle nazywanej pobierającą i ustawiającą .

Kiedy używasz tej właściwości w następujący sposób:

var cp = myClass.perimeter

wywołujesz kod zawarty w getbloku kodu, a kiedy używasz go w ten sposób:

myClass.perimeter = 5.0

wywołujesz kod zawarty w setbloku kodu, gdzie newValuejest on automatycznie wypełniany wartością podaną po prawej stronie operatora przypisania.

Obliczone właściwości mogą być do odczytu i zapisu, jeśli określono zarówno metodę pobierającą, jak i ustawiającą, lub tylko do odczytu, jeśli określono tylko metodę pobierającą.

Antonio
źródło
0

zmienna deklaruje i wywołuje w klasie w ten sposób

class X {
    var x: Int = 3

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

//value of x is:  3

teraz chcesz zaprogramować, aby domyślna wartość x była większa lub równa 3. Teraz weź hipotetyczny przypadek, jeśli x jest mniejsze niż 3, twój program zakończy się niepowodzeniem. więc chcesz, aby ludzie umieszczali 3 lub więcej niż 3. Swift ułatwił ci zadanie i ważne jest, aby zrozumieć ten nieco zaawansowany sposób datowania wartości zmiennej, ponieważ będą one szeroko wykorzystywane w programowaniu iOS. Zobaczmy teraz, jak zostanie tutaj użyte get and set.

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

jeśli nadal masz wątpliwości, pamiętaj, że użycie get and set służy do aktualizowania dowolnej zmiennej w sposób, w jaki chcemy, aby była aktualizowana. get and set da ci lepszą kontrolę nad twoją logiką. Potężne narzędzie, stąd niełatwe do zrozumienia.

saran
źródło