I keep getting this error and I don't understand why.
error: delegating initializers in structs are not marked with 'convenience'
This is what I have (as an example), a DeprecatedCurrency
and a SupportedCurrency
.
struct DeprecatedCurrency {
let code: String
}
struct SupportedCurrency {
let code: String
}
I then want to add a convenience init function for converting from the deprecated currency object to the new currency object. And this is what I have:
struct DeprecatedCurrency {
let code: String
}
struct SupportedCurrency {
let code: String
convenience init(_ currecny: DeprecatedCurrency) { // error!!
self.init(code: currecny.code)
}
init(code: String) {
self.code = code
}
}
What does this error even mean and how do I fix it?
I know that if we don't provide a default initializer, a initializer with signature init(code: String)
will be automatically generated for us with struct in Swift. So by the end of the day, what I am really looking for is (if possible):
struct SupportedCurrency {
let code: String
convenience init(_ currecny: DeprecatedCurrency) { // error!!
self.init(code: currecny.code)
}
}
Just remove the convenience
, it is not required for struct
.
From Swift
documentation.
Initializers can call other initializers to perform part of an instance’s initialization. This process, known as initializer delegation, avoids duplicating code across multiple initializers.
They haven't mentioned using convenience
. It is convenience
in semantic but doesn't require the keyword.
struct DeprecatedCurrency {
let code: String
}
struct SupportedCurrency {
let code: String
init(_ currency: DeprecatedCurrency) { // error!!
self.init(code: currency.code)
}
init(code: String) {
self.code = code
}
}
structs don't need the word convenience
Try this:
struct SupportedCurrency {
let code: String
init(_ currency: DeprecatedCurrency) { // error!!
self.init(code: currency.code)
}
init(code: String) {
self.code = code
}
}
The question is not why don't we put convenience
for structs but why do we put convenience
for classes. The reason is that classes have inheritance. With a class you need to call the super class's designated constructor (not sure if that is the correct terminology, it comes from Objective-C's initialsers.. The word convenience
marks the constructor as "not the designated constructor".
One option is to add the new init
in an extension
of your struct
. This way, you wont loose the default
auto generated memberwise initialiser.
struct SupportedCurrency {
let code: String
}
extension SupportedCurrency {
init(_ currency: DeprecatedCurrency) {
self.init(code: currency.code)
}
}
From Apple docs
NOTE
If you want your custom value type to be initializable with the default initializer and memberwise initializer, and also with your own custom initializers, write your custom initializers in an extension rather than as part of the value type’s original implementation. For more information, see Extensions.
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