繁体   English   中英

在Swift中将协议实现者升级为协议的通用方法

[英]Generic method to upcast protocol implementer to protocol in Swift

我想编写一种方法,以将实现协议的对象转换为其协议。

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

您可以尝试如下操作:

// 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)

扩展SequenceType也可以完成这项工作:

extension SequenceType {
    func upcast<T, U where Self.Generator.Element == T>() -> [U] {
        return flatMap {$0 as? U}
    }
}

归功于Anton Bronnikov,因为这只是他解决方案的另一种方式:)

要旨

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM