更新开始 这是因为这个阵列来自Objective-C,并且在整个过程中发生了一些搞砸事件。需要一些修复,但下面的所有答案都是正确的。 更新结束
我的协议如下
protocol SomeProtocol
{
func someFunctionProtocol
}
有一个结构实现此协议
struct SomeStruct: SomeProtocol
{
....
}
现在,在运行时,我得到一个我知道肯定会实现arg: Any
的参数SomeProtocol
我应该如何在arg
上调用此协议方法。我试过了
let ob = arg as! HanselProviderProtocol
,但这给了我运行时错误Could not cast value of type '_SwiftValue' (0x111952720) to 'SomeProtocol' (0x111957158)
下面的图片显示它无效
答案 0 :(得分:2)
在Swift3中,您可以将Any
类型的参数强制转换为协议:
protocol SomeProtocol {
func someFunctionProtocol()
}
struct SomeStruct: SomeProtocol {
func someFunctionProtocol() {
print("Yep")
}
}
func test(arg: Any) {
if let castee = arg as? SomeProtocol {
castee.someFunctionProtocol()
}
}
test(arg: SomeStruct())
打印:
Yep
答案 1 :(得分:1)
将Any
类型转换为struct
类型,而不是protocol
。
guard let ob = arg as? SomeStruct else {
print("invalid type")
return
}
ob.someFunctionProtocol()
修改强>
或者只需查看is
关键字。
let foo: Any = SomeStruct()
if foo is SomeProtocol {
// you can safely use force unwrapping here, because the condition above returned true
(foo as! SomeProtocol).someFunctionProtocol()
}
如果您要使用SwiftLint,可以使用以下命令禁用强制转换警告或错误:
// swiftlint:disable:this force_cast
答案 2 :(得分:1)
如果可能有更多不同的结构实现协议,请使用:
protocol SomeProtocol {
func a()
}
struct SomeStruct: SomeProtocol {
func a() {
print("a called from SomeStruct")
}
}
let x = SomeStruct() as Any // Just as an example
if let x = x as? SomeProtocol {
x.a()
}
答案 3 :(得分:1)
如果您的值为Any
,则可以测试一致性并执行如下:
(arg as? SomeProtocol)?.someFunction()
或者,如果您希望它具有更广泛的范围:
guard let conformer = arg as? SomeProtocol else { return }
conformer.someFunction()