What is the benefit of using a getter with no value. For example:
protocol xyz:Class{
var uuid:UUID{get}
}
I'll really appreciate your thoughts.
The code in your question is declaring a protocol. A protocol is basically a contract. It provides no functionality.
Your protocol's contract is stating that whatever conforms to the protocol must, at a minimum, provide a getter for a variable named uuid with a type of UUID.
The protocol itself does not provide the getter so it does not return a value. The class/struct/enum that conforms to the protocol will provide a value from the getter. This same class/struct/enum may also (if desired) provide a setter for the uuid variable as well. The protocol only states there must be a getter but it does not preclude the possibility of a setter.
The Protocols chapter in the Swift book shows examples and provides much more information on this. Specifically, the Property Requirements section covers protocol properties.
Related
This question already has answers here:
Read-only properties of protocols in Swift
(3 answers)
Why am I allowed to set a read only property of a protocol using a struct that inherits said protocol?
(3 answers)
Closed 2 years ago.
I'm currently a bit confused about gettable properties in protocols. Consider this example:
protocol Person {
var name: String { get }
}
I expected the name property to be read-only, but I found that you could change the value without compiler complaints:
struct Driver: Person {
var name: String
}
var driver = Driver(name: "Ryan")
driver.name = "Changed!"
If we define driver with let keyword, then compiler raises the error, but if I understand correctly, it has nothing to do with protocols, as constant structs are immutable by design in Swift.
Method interactions behave as I would've expected:
extension Person {
mutating func changeName(_ newName: String) {
self.name = newName // Error: 'name' is a get-only property
}
}
I'm new to Swift, and the nuance mentioned may not have any practical use, but this behavior made me ask myself if I lack some basic understanding of how structs work.
The protocol requirement is
a variable name which can be read
which doesn't mean that the variable in a struct adopting this protocol is necessarily read-only.
In the code you are changing the variable directly in the Driver type, the protocol is not involved.
On the other hand if you annotate the protocol type you get the expected error
var driver : Person = Driver(name: "Ryan")
driver.name = "Changed!" // Cannot assign to property: 'name' is a get-only property
A protocol only declares the required interface, but not the full interface of conforming types. Your conforming types can add extra properties/methods that aren't required by the protocol.
The same is true for getters and setter. If a protocol property requirement is get, that means the conformant type must have a getter for the property, but doesn't mean it cannot have a setter for it as well.
However, the same doesn't work the other way around. If a protocol declares a property as { get set }, that property must have a setter (be mutable).
The apple documentation explains this very well.
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.
I want to write a PAT and I don't care about Obj-C interoperability. The #nonobjc attribute sounds perfect but its designed for variables and methods only.
Anything similar for hiding protocols from Obj-C?
You seem to be misunderstood what the #nonobjc attribute is for:
From the docs:
nonobjc
Apply this attribute to a method, property, subscript, or initializer
declaration to suppress an implicit objc attribute.
If you scroll further down the page, it tells you what will have an implicit objc attribute on them:
The compiler implicitly adds the objc attribute to subclasses of any class defined in Objective-C. However, the subclass must not be generic, and must not inherit from any generic classes. [...] The objc attribute is also implicitly added in the following cases:
The declaration is an override in a subclass, and the superclass’s declaration has the objc attribute.
The declaration satisfies a requirement from a protocol that has the objc attribute.
The declaration has the IBAction, IBSegueAction, IBOutlet, IBDesignable, IBInspectable, NSManaged, or GKInspectable
attribute.
This does not include protocols, so protocols are never implicitly exposed to Objective-C. This means that you don't need the nonobjc attribute on protocols to suppress implicit objcs on protocols. Protocols, by default, are not exposed to Objective-C, unless you mark them with #objc.
I have a question about Protocol with associated type, why I can not make the protocol a type of my instance for example:
I know I can use Type Erasure to fix the issue, but why protocol with an associated type does not like to be a type of an instance, and if you will say because the associated type is also used as a constraint, well I want to implement the properties inside the protocol not inside its extensions since protocol extensions has the power to control who can access its properties, why we still have this issue.
Thank you.
There are lots of articles and answers (like this one) out there describing why but in summary, It needs associatedtype. Variables can not have an associatedtype. So alongside with Type Erasure method (that you don't want), you can simply make it opaque with adding some keyword to the type:
var objectA: some ProtocolA = A()
When defining a generic Swift protocol (that is, a protocol with at least one associatedtype) for a framework, it's common practice to also provide an Any... struct, e.g. SomethingType and AnySomething. For example, the standard library does this with AnySequence.
Is this necessary for a non-generic protocol? In that case, you can refer to the protocol type directly, so it seems that the protocol itself is already a type-erased version?
A protocol that does not have an associated type can easily be used as a Type in its own right. This is often done to allow diverse concrete types to be stored in collections identifying them only by a common protocol that all the concrete types implement.
Or to put it another way "type erasing" is a technique for dealing with protocols that have associated types. If your protocol does not have associated types, there is no need to employ the technique.
This question already has answers here:
Why Choose Struct Over Class?
(17 answers)
Closed 7 years ago.
I learn Swift from some time, I know the differences between structure and class. The main difference is structure is of value type and class is of reference type but didn't understand when to use structure instead of a class. Please explain it.
For example, In case of Protocols:
First, We have just a protocol of struct type:
protocol SomeProtocol{
func doSomeStuff()
}
Second, We make protocol of class type like this:
protocol SomeProtocol: class{
func doSomeStuff()
}
So, Please explain me, when we have to use protocol of struct type or of class type.
Firstly structs are passed by value (copied), and a class is passed by reference (copied just the memory address to the object).You may want to use structs for simpler types, because you get a free init for all the properties your struct has.And with protocols, the first one you can use it on class,struct and enum, the second you say that you only use that on classes,and you may want to put class if your protocol is a delegate or a data source,because you want the property(of the type of your protocol) weak to avoid the memory cycle. IMHO use classes for multi-scene apps because you don't need to take care to update value when you edited something in an another scene.
The protocol is not "of struct type" or "of class type", that is wrong terminology.
If you write SomeProtocol: class you make sure only classes can conform to that protocol, structs cannot. If you don't include the class both classes and structs can conform.
The docs (scroll down to "Class-Only Protocols") tell you that
You can limit protocol adoption to class types (and not structures or enumerations) by adding the class keyword to a protocol’s inheritance list. The class keyword must always appear first in a protocol’s inheritance list, before any inherited protocols.
Use a class-only protocol when the behavior defined by that protocol’s requirements assumes or requires that a conforming type has reference semantics rather than value semantics. For more on reference and value semantics, see Structures and Enumerations Are Value Types and Classes Are Reference Types.