Що таке "отримати" та "встановити" у Swift?


101

Я навчаюсь Swift і читаю The Swift Programming Languageз Apple, у мене немає фону Objective C (лише PHP, JS та інше, але немає Obj C)

На сторінці 24-25 я бачу цей код:

//...Class definition stuff...

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

//...Class continues...

Ця частина НЕ вказана в книзі, і я не можу отримати те, для чого вони потрібні.

Може хто - небудь пояснити мені , що отримати і набір є?


2
Ви читали сторінку 21 про геттер / сетер. Крім того, перші 30 піг або стільки - це екскурсія по Swift, а не повна документація.
vol7ron

Якщо ви зробили C ++, ви можете зв’язати цей матеріал з функціями getter та setter-члена класу
CodingOnSteroid

Відповіді:


38

Це фактично пояснено прямо перед кодом:

Крім простих властивостей, які зберігаються, властивості можуть мати геттер і сеттер.

class EquilateralTriangle: NamedShape {
    ...

Коли якийсь інший клас хоче отримати цю змінну периметра, вони роблять це:

let someVar = myTriangle.perimeter

... Що називає це:

get{
    return 3.0 * self.sideLength
}

Таким чином, це по суті, як якщо б виклик-контролер зробив це:

let someVar = 3.0 * myTriangle.sideLength

Коли ви встановлюєте змінну з іншого об'єкта, це виглядає приблизно так:

myTriangle.perimeter = 100

Що викликає код у set{}блоці:

set {
    sideLength = newValue / 3.0
}

І так, якби клас, який встановлює змінну, зробив це:

myTriangle.sideLength = 100/3.0

Це дійсно просто для зручності - ви можете зателефонувати цьому з іншого коду без необхідності ділити або множити на 3 постійно, тому що це робиться безпосередньо перед встановленням змінної та правою, перш ніж отримати змінну.

У Swift ми можемо мати властивості, які обчислюються при отриманні, і можуть робити щось під час встановлення. Ми могли б зробити це і в 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;
}

108

Отримання та встановлення змінних у межах класів стосується або отримання ("отримання"), або зміни ("налаштування") їх вмісту.

Розглянемо змінну membersкласу family. Природно, ця змінна повинна бути цілим числом, оскільки сім'я ніколи не може складатися з двох точок чогось люди.

Отже, ви, ймовірно, будете продовжувати, визначаючи membersподібну змінну:

class family {
   var members:Int
}

Це, однак, дасть людям, які використовують цей клас, можливість встановити кількість членів родини приблизно як 0 або 1. І оскільки немає такої речі, як сім'я 1 або 0, це дуже прикро.

Тут надходять геттери та сетери. Таким чином ви можете самостійно вирішити, як можна змінювати змінні та які значення вони можуть отримувати, а також вирішувати, який вміст вони повертатимуть.

Повертаючись до нашого сімейного класу, давайте переконайтеся, що ніхто не може встановити membersзначення на значення менше 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')
     }
   }
  }
}

Тепер ми можемо отримати доступ до membersзмінної, як і раніше, ввівши instanceOfFamily.members, і завдяки функції setter ми також можемо встановити її значення, як і раніше, ввівши, наприклад:instanceOfFamily.members = 3 . Однак, що змінилося, це той факт, що ми не можемо встановити цю змінну більше ніж 2.

Зверніть увагу на введення _membersзмінної, яка є фактичною змінною для зберігання значення, яке ми встановили за допомогою membersфункції сеттера. Оригінал membersтепер став обчисленою властивістю, це означає, що він діє лише як інтерфейс для обробки нашої фактичної змінної.


members==> count, numberOfMembers; var members : Set<Person>??
GoZoner

1
set (newVal) { ... }, newVal мається на увазі, так set { _members = newVal }само правильно.
AndreasHassing

4
Зауважте, що подібні змінні _membersповинні бути приватними, інакше команда instanceOfFamily._members=1встановить instanceOfFamily.membersзначення нижче 2
Даніель,

Схоже, параметр за замовчуванням названий newValueу Swift 4 - docs.swift.org/swift-book/LanguageGuide/Properties.html#ID260
Нолан Емі

18

Просте запитання повинно супроводжуватися короткою, простою і зрозумілою відповіддю.

  • Коли ми отримуємо цінність майна, вона звільняє свою get{}частину.

  • Коли ми встановлюємо значення властивості, воно заповнює його set{}частину.

PS. Встановлюючи значення для властивості, SWIFT автоматично створює константу з назвою "newValue" = значення, яке ми встановлюємо. Після постійної "newValue" стає доступною у власністьset{} .

Приклад:

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

1
чи обов’язково призначати значення за замовчуванням для доступу учасника з-за класу. У мене була ця проблема, як виправлена, коли я призначаю значення за замовчуванням для цього класу UserBean: NSObject {var user_id: String? = nil} доступ до нього як наступний дозволений користувачеві: UserBean = UserBean () user.user_id = "23232332"
Amr Angry

1

Ви повинні подивитися на обчислювані властивості

У вашому зразку коду perimeterє властивість, не підкріплена змінною класу, натомість її значення обчислюється за допомогою getметоду та зберігається за допомогою setметоду - зазвичай його називають getter та setter .

Коли ви використовуєте цю власність так:

var cp = myClass.perimeter

ви викликаєте код, що міститься в getблоці коду, і коли ви використовуєте його так:

myClass.perimeter = 5.0

ви викликаєте код, що міститься в setблоці коду, де newValueавтоматично заповнюється значення, надане праворуч від оператора присвоєння.

Обчислені властивості можна зчитувати, якщо записати і геттер, і сеттер, або лише тоді, якщо вказано лише геттер.


0

змінна декларує та називає так у класі

class X {
    var x: Int = 3

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

//value of x is:  3

тепер ви хочете програмувати значення за замовчуванням x більше або рівне 3. Тепер візьміть гіпотетичний випадок, якщо х менше 3, ваша програма вийде з ладу. Таким чином, ви хочете, щоб люди ставили 3 або більше 3. Swift вам це легко зрозумів, і важливо зрозуміти цей заздалегідь розрядний спосіб знайомства зі змінною величиною, оскільки вони широко використовуватимуться в розробці iOS. Тепер давайте подивимося, як тут використовуватиметься налаштування та налаштування.

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

якщо у вас все ще виникають сумніви, пам’ятайте, використання get and set - це оновлення будь-якої змінної так, як ми хочемо, щоб вона була оновлена. get and set дасть вам кращий контроль для управління вашою логікою. Потужний інструмент, отже, не легко зрозумілий.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.