Swift协议实现协议的通用方法

时间:2015-10-31 17:55:24

标签: swift generics

我想编写一个方法来向对象实现协议的转发。

例如,我们假设我们有一个协议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协议?

2 个答案:

答案 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的信任,因为这只是他解决方案的另一种方式:)

Gist