我想编写一个方法来向对象实现协议的转发。
例如,我们假设我们有一个协议Drawable
,以及一个实现它的结构(或类)Shape
。
protocol Drawable {}
struct Shape: Drawable {}
我希望有一个不可用的上传,如:
let shape = Shape()
let drawable: Drawable = upcast(shape)
到目前为止,我最接近的解决方案如下。但是,我不知道如何指定T
实现U
,因此结果/类型转换不需要是可选的/可用的。
func upcast<T, U>(object: T) -> U? {
return object as? U
}
所以我能做到:
let shape = Shape()
let drawable: Drawable? = upcast(shape)
所有这一切的重点在于我希望能够做到这一点:
let shapes = [shape]
let drawables: [Drawable] = shapes
是否可以编写一个通用方法,说T
实现U
,是U协议?
答案 0 :(得分:1)
您可以尝试以下内容:
// This is your function
func upcast<T, U>(instance: T) -> U? {
return instance as? U
}
// This is what you can use to upcast sequence into an array
func flatUpcast<S: SequenceType, T, U where S.Generator.Element == T>(sequence: S) -> [U] {
return sequence.flatMap() {
upcast($0)
}
}
// Playground try-out
protocol Drawable { }
struct Shape: Drawable { }
let shape = Shape()
let shapes = [shape, shape, shape]
let drawables: [Drawable] = flatUpcast(shapes)
答案 1 :(得分:1)
扩展SequenceType
也可以完成这项工作:
extension SequenceType {
func upcast<T, U where Self.Generator.Element == T>() -> [U] {
return flatMap {$0 as? U}
}
}
对Anton Bronnikov的信任,因为这只是他解决方案的另一种方式:)