I just defined a very simple protocol and a a class using generics which can handle this protocol.
In the lines marked with error you will get the error: "Cannot assign to 'flag' in 'aObj'.
protocol Flag {
var flag: Bool {get set}
}
class TestFlag<T: Flag> {
func toggle(aObj: T) {
if aObj.flag {
aObj.flag = false; // <--- error
} else {
aObj.flag = true; // <--- error
}
}
}
Do you have an idea why and what I have to change to fix it?
In Swift, a protocol defines a blueprint of methods or properties that can then be adopted by classes (or any other types). We use the protocol keyword to define a protocol. For example, protocol Greet { // blueprint of a property var name: String { get } // blueprint of a method func message() }
Protocol is a very powerful feature of the Swift programming language. Protocols are used to define a “blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality.”
In Swift, protocols contain multiple abstract members. Classes, structs and enums can conform to multiple protocols and the conformance relationship can be established retroactively.
In iOS development, a protocol is a set of methods and properties that encapsulates a unit of functionality. The protocol doesn't actually contain any of the implementation for these things; it merely defines the required elements.
From the docs:
Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake.
In this case, you can add inout
so that the toggle is persisted beyond your function call:
func toggle(inout aObj: T) {
if aObj.flag {
aObj.flag = false;
else {
aObj.flag = true;
}
}
You could have also done:
func toggle(var aObj: T) {
}
but that might not achieve what you wanted.
manojlds answer is correct and therefore I accepted it.
Nevertheless there was a similar answer some days ago with the same solution but with a other argumentation (seems now deleted).
The argumentation was about that the compliler can not know if the protocol is used for a class, a struct or a enum. With Swift, protocols can by applied on all this types. But struct instances use a by-value call and for classes instances (objects) it us a by-reference call.
From my perspective this answer was correct too, because you can solve the problem with a 2nd solution:
@objc
protocol Flag {
var flag: Bool {get set}
}
Just add the @obj attriute on the protocol. As a result you can use this protocol only for a class which lead to the result only by-refernece calls are allowd. Therefore the compiler don't need anymore the inout
information.
But I searched for a solution to increase the reuse of the protocol and use now manojlds suggestions.
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