Let's say that I have the following protocol:
protocol Identifiable { var id: Int {get} var name: String {get} }
And that I have the following structs:
struct A: Identifiable { var id: Int var name: String } struct B: Identifiable { var id: Int var name: String }
As you can see, I had to 'conform' to the Identifiable protocol in struct A and struct B. But imagine if I had N more structs that needs to conform to this protocol... I don't want to 'copy/paste' the conformance (var id: Int, var name: String)
So I create a protocol extension:
extension Identifiable { var id: Int { return 0 } var name: String { return "default" } }
With this extension now I can create a struct that conforms to the Identifiable protocol without having to implement both properties:
struct C: Identifiable { }
Now the problem is that I can't set a value to the id property or the name property:
var c: C = C() c.id = 12 // Cannot assign to property: 'id' is a get-only property
This happens because in the Identifiable protocol, id and name are only gettable. Now if I change the id and name properties to {get set} I get the following error:
Type 'C' does not conform to protocol 'Identifiable'
This error happens because I haven't implemented a setter in the protocol extension... So I change the protocol extension:
extension Identifiable { var id: Int { get { return 0 } set { } } var name: String { get { return "default" } set { } } }
Now the error goes away but if I set a new value to id or name, it gets the default value (getter). Of course, the setter is empty.
My question is: What piece of code do I have to put inside the setter? Because if I add self.id = newValue it crashes (recursive).
Thanks in advance.
Extensions in Swift can: Add computed instance properties and computed type properties. Define instance methods and type methods. Provide new initializers.
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.
error: extensions may not contain stored properties . It means that Swift doesn't support stored properties inside the extension. Therefore, we cannot use the toggleState property to keep the internal state of our toggle button. For this reason, we need a workaround.
Protocol Default Implementation “You can use protocol extensions to provide a default implementation to any method or computed property requirement of that protocol.” In fact, not only can you provide a default implementation to methods or computed properties defined in the protocol, you can also add new ones.
Extensions in Swift can: Add computed instance properties and computed type properties In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of. For more details, see Protocol Extensions.
In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of. For more details, see Protocol Extensions. Extensions can add new functionality to a type, but they cannot override existing functionality.
This example adds five computed instance properties to Swift’s built-in Double type, to provide basic support for working with distance units: These computed properties express that a Double value should be considered as a certain unit of length.
Because protocols are types, begin their names with a capital letter (such as FullyNamed and RandomNumberGenerator) to match the names of other types in Swift (such as Int, String, and Double ). Here’s an example of a protocol used as a type: This example defines a new class called Dice, which represents an n -sided dice for use in a board game.
It seems you want to add a stored property
to a type via protocol extension. However this is not possible because with extensions you cannot add a stored property.
I can show you a couple of alternatives.
The easiest way (as probably you already imagine) is using classes instead of structs.
class IdentifiableBase { var id = 0 var name = "default" } class A: IdentifiableBase { } let a = A() a.name = "test" print(a.name) // test
Cons: In this case your A class needs to inherit from
IdentifiableBase
and since in Swift theres is not multiple inheritance this will be the only class A will be able to inherit from.
This technique is pretty popular in game development
struct IdentifiableComponent { var id = 0 var name = "default" } protocol HasIdentifiableComponent { var identifiableComponent: IdentifiableComponent { get set } } protocol Identifiable: HasIdentifiableComponent { } extension Identifiable { var id: Int { get { return identifiableComponent.id } set { identifiableComponent.id = newValue } } var name: String { get { return identifiableComponent.name } set { identifiableComponent.name = newValue } } }
Now you can make your type conform to Identifiable
simply writing
struct A: Identifiable { var identifiableComponent = IdentifiableComponent() }
Test
var a = A() a.identifiableComponent.name = "test" print(a.identifiableComponent.name) // test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With