I made an protocol Stringify to convert Types that implement the protocol to a String.
protocol Stringify {
func stringify() -> String
}
extension Collection where Iterator.Element == Stringify {
/// changes all the elements in the collection to a String
func stringify() -> [String] {
var strings = [String]()
if let elements = self as? [Stringify] {
for element in elements {
strings.append(element.stringify())
}
}
return strings
}
}
extension Int: Stringify {
func stringify() -> String {
return String(self)
}
}
extension Double: Stringify {
func stringify() -> String {
return String(self)
}
}
let test = [5,6,7]
/// does work
[6,5,34].stringify()
/// does not work -> Error alert
test.stringify()
But when I set a collection of Ints to a property and using then stringify() on it, it does not work.
Error:
Referencing instance method 'stringify()' on 'Collection' requires the types 'Int' and 'Stringify' be equivalent
If I use it directly everything is going fine.
What is the problem here?
extension Collection where Iterator.Element == Stringify
has a “same type requirement” and defines an extension for collections whose elements are of the type Stringify
. But test
is an array of Int
, i.e. the elements conform to the Stringify
protocol. So what you want is
extension Collection where Iterator.Element : Stringify
or, equivalently,
extension Collection where Element : Stringify
The reason that
/// does work
[6,5,34].stringify()
compiles with your original definition is that the compiler infers the type of the array as [Stringify]
from the context.
let test: [Stringify] = [5,6,7]
test.stringify()
would compile as well.
Note that there is no need to cast self
in the extension method. You can simplify the implementation to
func stringify() -> [String] {
var strings = [String]()
for element in self {
strings.append(element.stringify())
}
return strings
}
or just
func stringify() -> [String] {
return self.map { $0.stringify() }
}
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