I want to have the following types:
Renderable
= Protocol/Interface with function render()
Bag<T>
= Renderable, OrderedDictionary<String, T> where T = Renderable
Bag
= Bag<Renderable>
(shorthand without T
-type specification, just assuming it is Renderable
)This will ensure, I can render()
everything. And in Bag
I can store anything Renderable
, either providing the specific types or not.
The C# version looks like this:
public class Bag : Bag<object> {}
public class Bag<T> : Dictionary<string, T> {
public override string ToString() => ToString("");
public string ToString(string separator) => string.Join(separator, this.Values);
}
Trying to translate this into Swift:
public protocol Renderable {
func render() -> String
}
import OrderedCollections
public typealias Bag<T> = OrderedDictionary<String, T> where T: Renderable
extension Bag: Renderable {
public func render() -> String {
render(separator: "")
}
public func render(separator: String = "") -> String {
if count == 0 { return ""}
return map {
$0.value.render() <-- compilers says: value has no member "render"
}.joined(separator: separator)
}
}
Q1: Why does Swift think, $0.value
, which is a T
, which is constraint to Renderable
has no function render()
?
Q2: How would I define a simple type Bag
like the C# version, like
public typealias Bag = Bag<Renderable>
Since you want to store any type that conforms to Renderable in your dictionary you can simply skip the generic T in the typealias and directly use the protocol instead
public typealias Bag = OrderedDictionary<String, Renderable>