解压缩可选作为实现接口的条件对象

时间:2016-06-28 23:32:01

标签: swift

我正在尝试实现一个函数,如果函数返回的可选对象实现了特定的协议,则会有条件地调用它。我正在努力学习语法...它告诉我:

Braced block of statements is an unused closure

Expected { after if condition

示例:

class SomeType {
}

class Something {
    func doSomething()
}

protocol Foo {
    func foo() -> SomeType
}

class Bar {
    var whatever : SomeThing
}

extension Bar {
    var handler : SomeThing? {
        return whatever
    }
}

class FooBar {
    func doSomething(bar : Bar) {
        // Assuming that bar's handler is set and implements Foo then use foo...
        let foo = bar.handler as SomeThing : Foo {
            ...
            foo.doSomething()
            ...
            foo.foo()
        }
    }
}

我可以这样做:

if let foo = bar.handler! as? Something {
    if (foo is Foo) {
        foo.doSomething()
        (foo as Foo).foo()
    }
}

或者这个:

if let fubar = bar.handler! as? Something, let foo = fubar as? Foo {
    fubar.doSomething()
    foo.foo()
}

但我希望有一种更清洁的方式

2 个答案:

答案 0 :(得分:0)

从这段代码中可以清楚地知道你正在尝试做什么,但是如果你想要完全动态地做这件事(在运行时决定一切)你很可能会战斗迅速。这通常是可能的,但在每一个转折点,你都会与语言的范例作斗争。您通常处理您所描述的内容的方式是使用重载,以便在编译时而不是运行时确定:

func doSomething<F: Foo>(handler : F) { ... things when F is Foo ... } 

通过这种方式混合很多类+泛型+协议往往是一个非常痛苦的根源,所以你应该仔细询问为什么Bar是一个类而不是一个结构(至少为什么它&#39;不是final class)。很难从这种高度风格化的问题中给出确切的建议,所以关于你试图解决的问题的更多结构可能会有所帮助。

所有这一切,你通常可以做你所描述的。你的语法不正确。你的意思是:

    if let foo = bar.handler as? Foo {

答案 1 :(得分:0)

这似乎是最干净的方法。

if let foo:Something = bar.handler! where foo is Foo {
    foo.doSomething()
    (foo as Foo).foo()
}