【问题标题】:How can I use type(of: someVar) as a proper Type in Swift?如何在 Swift 中使用 type(of: someVar) 作为正确的类型?
【发布时间】:2017-10-23 20:20:44
【问题描述】:

如何在 Swift 中使用 type(of: someVar) 作为正确的类型?

假设我有一些通用协议 Requestable:

protocol Decryptable: Decodable {
    var cipher: Cipher
}
protocol Requestable {
    associatedtype T
    var schema: T
}
protocol Service {
    static func invoke<R: Requestable>(_ request: R) -> Void where R.T: Decodable {
    // impl. #1
    }
    static func invoke<R: Requestable>(_ request: R) -> Void where R.T: Decryptable {
    // impl. #2
    }
}
struct Request<T>: Requestable {
    var schema: T
}

服务可以调用其 Schema 可解码或可解密的请求。

但是,由于 Decryptable 符合 Decodable,因此在其他地方我们有一些 Decryptable 值已向上转换为 Decodable,例如:

let myDecodable = myDecryptable as Decodable
// later... in a class that doesn’t know about myDecryptable...
let myRequest = Request(schema: myDecodable)
Service.invoke(myRequest)

现在,当此处调用 Service 调用时,它将路由到第一个实现 (#1)。即,由于请求是使用向上转换的值“myDecodable”创建的,invoke 将转到实现#1(好像 Request.T 只是一些可解码类型,而实际上它是可解密的,在引擎盖下)。

确实,如果我在 XCode 中设置断点,运行时会清楚地知道 Request.T 在任何情况下都是 Decryptable 类型,即使在 is upcast 之后也是如此。

所以在实现 1 中,我尝试了很多方法来将架构可解密的调用路由到实现 2:

typealias ActualType: Decryptable = R.T
if let downcastedRequest = request as? Request<ActualType> {
     invoke(downcastedRequest)
}
// FAILS to compile    

let schemaType = type(of: request.schema)
if let downcastedRequest = Request<schemaType>(schema: request.schema as? schemaType)  {
     invoke(downcastedRequest)
}
// FAILS to compile


if let downcastedRequest = Request<type(of: request.schema)>(schema: request.schema as? type(of: request.schema))  {
     invoke(downcastedRequest)
}
// FAILS to compile

请帮忙,谢谢。 (我是否愚蠢地尝试使用具有关联类型的协议?为什么我不能在这里使用 type(of: schema) 就好像它是正确的类型一样......?

【问题讨论】:

  • 没有回答您的问题,但 Swift 4 中有一个 Decodable 协议,用于反序列化。我猜你的Decodable 与密码学有关,对吗?

标签: swift generics swift4 swift-protocols associated-types


【解决方案1】:

使用 == 代替:

<...>
where R.T == Decodable <...>
where R.T == Decryptable <...>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多