Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Protocol get only settable?

why can I do this without any error:

var testDto = ModelDto(modelId: 1) testDto.objectId = 2 

while I define this:

protocol DataTransferObject {     var objectType: DtoType { get }     var parentObjectId: Int { get set }     var objectId: Int { get }     var objectName: String { get set } }  struct ModelDto: DataTransferObject {     var objectType: DtoType     var parentObjectId: Int     var objectId: Int     var objectName: String      init(modelId: Int) {         self.objectType = DtoType.Model         self.objectId = modelId         self.parentObjectId = -1         self.objectName = String()     } } 

If the definition in my protocol is mostly ignored (getter, setter definition), why should I use them anyway?

like image 373
Artur Pajonk Avatar asked Jun 01 '15 12:06

Artur Pajonk


People also ask

What is get set in protocol Swift?

protocol s defines what name has to be in the struct or class that it attached to. If the has { get } then it can be let or var , however if it a { get set } then has to a var only. The advantage is that if someone uses a protocol on a struct or class then those names have to be there.

Can we make protocol only class specific struct can not adopt it?

A protocol defines a blueprint of methods, properties, and other requirements. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements. But there would be a time when you want to restrict protocols to be adopted by a specific class.

Can Swift protocols have properties?

Protocols provide a blueprint for Methods, properties and other requirements functionality. It is just described as a methods or properties skeleton instead of implementation. Methods and properties implementation can further be done by defining classes, functions and enumerations.

How do you use a variable in protocol?

Property requirements are always declared as variable properties, prefixed with the var keyword. Gettable and settable properties are indicated by writing { get set } after their type declaration, and gettable properties are indicated by writing { get } . var height: Int {return 5} // error!


2 Answers

Apple states in the "Swift Programming Language (Swift 3)":

If the protocol only requires a property to be gettable, the requirement can be satisfied by any kind of property, and it is valid for the property to be also settable if this is useful for your own code.

For this reason, the five following Playground code snippets are all valid:

Example #1: constant property

protocol FullyNamed {     var fullName: String { get } }  struct Duck: FullyNamed {     let fullName: String }  let scrooge = Duck(fullName: "Scrooge McDuck") print(scrooge.fullName) // returns "Scrooge McDuck" 

Example #2: variable property

protocol FullyNamed {     var fullName: String { get } }  struct Duck: FullyNamed {     var fullName: String         }      var scrooge = Duck(fullName: "Scrooge McDuck") print(scrooge.fullName) // returns "Scrooge McDuck"  scrooge.fullName = "Scrooge H. McDuck" print(scrooge.fullName) // returns "Scrooge H. McDuck" 

Example #3: computed property (get only)

protocol FullyNamed {     var fullName: String { get } }  struct Duck: FullyNamed {     private var name: String     var fullName: String {         return name     } }  let scrooge = Duck(name: "Scrooge McDuck") print(scrooge.fullName) // returns "Scrooge McDuck" 

Example #4: computed property (get and set)

protocol FullyNamed {     var fullName: String { get } }  struct Duck: FullyNamed {     private var name: String     var fullName: String {         get {             return name         }         set {             name = newValue         }     } }  var scrooge = Duck(name: "Scrooge McDuck") print(scrooge.fullName) // returns "Scrooge McDuck"  scrooge.fullName = "Scrooge H. McDuck" print(scrooge.fullName) // returns "Scrooge H. McDuck" 

Example #5: private(set) variable property

/* Duck.swift located in Sources folder */  protocol FullyNamed {     var fullName: String { get } }  public struct Duck: FullyNamed {     public private(set) var fullName: String      public init(fullName: String) {         self.fullName = fullName     }      public mutating func renameWith(fullName: String) {         self.fullName = fullName     } }  /* Playground file */  var scrooge = Duck(fullName: "Scrooge McDuck") print(scrooge.fullName) // returns "Scrooge McDuck"  scrooge.renameWith("Scrooge H. McDuck") print(scrooge.fullName) // returns "Scrooge H. McDuck" 

Apple also states:

If a protocol requires a property to be gettable and settable, that property requirement cannot be fulfilled by a constant stored property or a read-only computed property.

For this reason, the two following Playground code snippets ARE NOT valid:

Example #1: constant property

protocol FullyNamed {     var fullName: String { get set } }  struct Duck: FullyNamed {     let fullName: String }  let scrooge = Duck(fullName: "Scrooge McDuck") // Error message: Type 'Duck' does not conform to protocol 'FullyNamed' 

Example #2: computed property (get only)

protocol FullyNamed {     var fullName: String { get set } }  struct Duck: FullyNamed {     private var name: String     var fullName: String {         return name     } }  var scrooge = Duck(name: "Scrooge McDuck") // Error message: Type 'Duck' does not conform to protocol 'FullyNamed' 

Example #3: computed property (get only)

protocol FullyNamed {     var fullName: String { get } }  struct Duck: FullyNamed {     var fullName: String {return "Scrooge McDuck"}      init(fullName: String) {         self.fullName = fullName    // Error Message Cannot assign to Property: "FullName" is get only     } } 
like image 154
Imanou Petit Avatar answered Sep 23 '22 16:09

Imanou Petit


As per the official documentation:

The getter and setter requirements can be satisfied by a conforming type in a variety of ways. If a property declaration includes both the get and set keywords, a conforming type can implement it with a stored variable property or a computed property that is both readable and writeable (that is, one that implements both a getter and a setter). However, that property declaration can’t be implemented as a constant property or a read-only computed property. If a property declaration includes only the get keyword, it can be implemented as any kind of property.

like image 21
Ankit Goel Avatar answered Sep 23 '22 16:09

Ankit Goel