Быстрые протоколы: разница между {get} и {get set} с конкретными примерами? - PullRequest
0 голосов
/ 11 января 2019

Я довольно новичок в Swift, и хотя я прочитал документацию Apple и многие темы и темы по этому поводу, я все еще не могу понять, в чем разница между { get } и { get set }. Я имею в виду, я ищу объяснение на конкретном примере.

Как, например,

protocol PersonProtocol {
    var firstName: String { get }
    var lastName: String { get set }
}

Какова будет действительная разница между этими двумя свойствами? Я пытался играть с этими свойствами на детской площадке:

struct Person: PersonProtocol {
    var firstName: String
    var lastName: String
}

var p = Person(firstName: "John", lastName: "Lennon")
print(p.firstName) // John
print(p.lastName) // Lennon
p.firstName = "Paul"
p.lastName = "McCartney"
print(p.firstName) // Paul
print(p.lastName) // McCartney

Не помогло ... Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 11 января 2019

protocol - это требование некоторого минимального интерфейса типа, его реализующего.

  • var name: Type { get } требует, чтобы у типа было свойство по крайней мере с getter (доступно извне типа, но не private), т.е. внешний код должен иметь возможность прочитайте стоимость имущества. В типе реализации это могут быть let name: Type, var name: Type, private(set) var name: Type, fileprivate(set) var name: Type и т. Д.

  • var name: Type { get set } требует, чтобы тип имел свойство с обоими доступными getter и setter, т.е. внешний код должен иметь возможность читать и записывать к собственности. Здесь разрешается только var name: Type.

Если protocol требуется для getter, но вы также предоставляете setter - это не противоречит protocol требованиям. Но если для protocol требуется и для getter, и для setter - вы должны предоставить оба, и отсутствие любого из них не будет действительной реализацией.


Ваш Person класс определил оба свойства как var (с доступными getter и setter), поэтому вы можете изменить их оба. Но PersonProtocol не требуется способность устанавливать firstName.

И, как показывает @JoakimDanielson, если вы будете использовать только интерфейс, необходимый для protocol, вам не придется изменять значение firstName.

0 голосов
/ 11 января 2019

Вы создаете переменную типа Person, и на эту структуру нет ограничений. Если вместо этого вы создадите переменную типа PersonProtocol, то firstName будет доступен только для чтения

var p1: PersonProtocol = Person(firstName: "John", lastName: "Lennon")
print(p1.firstName) // John
print(p1.lastName) // Lennon
p1.firstName = "Paul" <== error: cannot assign to property: 'firstName' is a get-only property
...