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



如何在Swift中将type(of: someVar)用作正确的Type?

假设我有一些通用协议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
}

服务可以调用架构为可解码或可解密的请求。

然而,由于Decryptoble符合Decodeable,因此在其他地方,我们有一些Decryptoable值已升级为Decodeble,如:

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

现在,当这里调用Service invoke时,它将路由到第一个实现(#1)。也就是说,由于请求是用upcasted值"myDecodeable"创建的,invoke将转到实现#1(就好像request.T只是某种Decodeable类型,而实际上它是可解密的)。

事实上,如果我在XCode中设置断点,运行时就会清楚地知道Request.T在任何情况下都是可解密的类型,即使在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

请帮忙,谢谢。(我尝试使用关联类型的协议是愚蠢的吗?为什么我不能在这里使用类型(of:schema),就好像它是一个合适的类型一样…?)。。?

使用==代替:

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

最新更新