Swift 向下转换时出错 'Any'
Swift error while downcasting 'Any'
以下代码几乎是 Apple Documentation 的复制品并且编译没有错误:
guard let firstItem = (rawItems! as? Array<Dictionary<String, Any>>)?.first else {
throw AnError()
}
let identityRef = firstItem[kSecImportItemIdentity as String]
as! SecIdentity? // !!!
guard let identity = identityRef else {
throw AnError()
}
标记为!!!
的行包含强制向下转换,而将as!
替换为as
很明显会导致编译错误'Any?' is not convertible to 'SecIdentity?'...
确实SecIdentity
是class 而 Any
甚至可能不是 class.
我真的无法解释的是以下内容。如果我试图通过使用 this
使代码更安全
guard let idenity = firstItem[kSecImportItemIdentity as String] as? SecIdentity
else {
throw AnError()
}
或这个
guard let idenityRef = firstItem[kSecImportItemIdentity as String] as? SecIdentity?
else {
throw AnError()
}
我得到一个编译错误:Conditional downcast to CoreFoundation type 'SecIdentity' will always succeed
CoreFoundation 类型的行为与 Foundation 类型略有不同。
不要有条件的贬低身份。如果可选绑定成功,您可以强制解包身份
guard let idenity = firstItem[kSecImportItemIdentity as String] else { throw AnError() }
var privateKey : SecKey?
let status = SecIdentityCopyPrivateKey(identity as! SecIdentity, &privateKey)
旁注:
请不要写as? SecIdentity?
.
要么是有条件的向下转换 as? SecIdentity
要么是桥接转换一个可选的 as SecIdentity?
SecIdentity
是“代表身份的抽象核心基础类型对象”,核心基础类型的类型可以是
用 CFGetTypeID()
检查。所以你可以先检查类型ID。如果它匹配一个
SecIdentity
那么强制转换是安全的:
guard let cfIdentity = firstItem[kSecImportItemIdentity as String] as CFTypeRef?,
CFGetTypeID(cfIdentity) == SecIdentityGetTypeID() else {
throw AnError()
}
let identity = cfIdentity as! SecIdentity
另请参阅错误报告 SR-7015 The CoreFoundation conditional downcast diagnostic is not as helpful as it should be:
The diagnostic should be updated with a message that informs the developer to compare CFTypeIds (with a fixit if possible).
以下代码几乎是 Apple Documentation 的复制品并且编译没有错误:
guard let firstItem = (rawItems! as? Array<Dictionary<String, Any>>)?.first else {
throw AnError()
}
let identityRef = firstItem[kSecImportItemIdentity as String]
as! SecIdentity? // !!!
guard let identity = identityRef else {
throw AnError()
}
标记为!!!
的行包含强制向下转换,而将as!
替换为as
很明显会导致编译错误'Any?' is not convertible to 'SecIdentity?'...
确实SecIdentity
是class 而 Any
甚至可能不是 class.
我真的无法解释的是以下内容。如果我试图通过使用 this
使代码更安全guard let idenity = firstItem[kSecImportItemIdentity as String] as? SecIdentity
else {
throw AnError()
}
或这个
guard let idenityRef = firstItem[kSecImportItemIdentity as String] as? SecIdentity?
else {
throw AnError()
}
我得到一个编译错误:Conditional downcast to CoreFoundation type 'SecIdentity' will always succeed
CoreFoundation 类型的行为与 Foundation 类型略有不同。
不要有条件的贬低身份。如果可选绑定成功,您可以强制解包身份
guard let idenity = firstItem[kSecImportItemIdentity as String] else { throw AnError() }
var privateKey : SecKey?
let status = SecIdentityCopyPrivateKey(identity as! SecIdentity, &privateKey)
旁注:
请不要写as? SecIdentity?
.
要么是有条件的向下转换 as? SecIdentity
要么是桥接转换一个可选的 as SecIdentity?
SecIdentity
是“代表身份的抽象核心基础类型对象”,核心基础类型的类型可以是
用 CFGetTypeID()
检查。所以你可以先检查类型ID。如果它匹配一个
SecIdentity
那么强制转换是安全的:
guard let cfIdentity = firstItem[kSecImportItemIdentity as String] as CFTypeRef?,
CFGetTypeID(cfIdentity) == SecIdentityGetTypeID() else {
throw AnError()
}
let identity = cfIdentity as! SecIdentity
另请参阅错误报告 SR-7015 The CoreFoundation conditional downcast diagnostic is not as helpful as it should be:
The diagnostic should be updated with a message that informs the developer to compare CFTypeIds (with a fixit if possible).