在实现协议的结构上调用方法

时间:2017-01-18 11:29:20

标签: swift

更新开始 这是因为这个阵列来自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)

下面的图片显示它无效

Struct Defn

===== Debug

4 个答案:

答案 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()