I have a Vector struct with a generic type T that adheres to the FloatingPoint protocol. I would like to provide a custom description for printing formatted values from the Vector. The example below only works for the Double type. I can't make another extension for the Float type because there can't be another conformance with CustomStringConvertible. How do I format the generic T in the CustomStringConvertible description for both Double and Float types?
public struct Vector<T: FloatingPoint> {
public var values: [T]
public init(_ values: [T]) {
self.values = values
}
public init(size: Int, fill: T = 0.0) {
self.values = [T](repeating: fill, count: size)
}
public subscript(item: Int) -> T {
get { return values[item] }
set { values[item] = newValue }
}
}
extension Vector: CustomStringConvertible where T == Double {
public var description: String {
var des = [String]()
for val in self.values {
des.append(val.formatted(.number.precision(.significantDigits(2))))
}
return "<\(des.joined(separator: " "))>"
}
}
extension Vector: CustomStringConvertible {
public var description: String {
var des = [String]()
for value in self.values {
if let val = value as? Double {
des.append(val.formatted(.number.precision(.fractionLength(2))))
} else if let val = value as? Float {
des.append(val.formatted(.number.precision(.fractionLength(1))))
} else {
des.append("\(value)")
}
}
return "<\(des.joined(separator: " "))>"
}
}
This looks much more clever than the solution I came up with. Can you explain the benefits of doing it this way compared to my solution? I assume it runs faster since there are no if-let statements. Also, why did you use values instead of self.values and formatted instead of self.formatted ?
Thank you for the explanation. I need to learn more about protocols in Swift. They seem to be an important feature of Swift, especially when developing a Swift package.