在Swift中使用return模拟宏

时间:2015-02-14 00:50:22

标签: objective-c swift macros

在Obj-C中,我可以定义一个宏

#define check_nil(x) if (!x) { return nil }

可用于测试函数是否返回nil(表示错误),如果是这种情况,调用者只需返回nil - 将错误传播到堆栈中。我正在编写解析器,这种模式经常发生。 E.g。

- (id)caller {
    ...
    id z = [self callee];
    check_nil(z);
    ...
}

- (id)callee {
    ...
}

不幸的是,在转向swift之后,宏已经消失了。函数(使用@autoclosure)将替换它们,但不是在这种情况下。现在,我的代码中充斥着相同的if项检查。

有任何想法在Swift中复制同样的东西吗?

1 个答案:

答案 0 :(得分:1)

您无法完全实现该模式。

也许您可以使用一种类型,如果它们返回nil,将会将未来的操作变为无操作:

struct NonNil<T> {
    var cantBeNil: T?

    mutating func update(withClosure: () -> T?) {
        if self.cantBeNil != nil {
            self.cantBeNil = withClosure()
        }
    }
}

然后你可以这样使用这个结构:

func myFunc() -> String? {
    var nonNil = NonNil(cantBeNil: "")

    nonNil.update {
        // some action
        return "new value"
    }

    nonNil.update {
        // another action that ends up returning nil
        return nil
    }

    // The rest of these don't end up calling the closure
    nonNil.update {
        println("not called")
        return ""
    }

    nonNil.update {
        println("not called")
        return ""
    }

    return nonNil.cantBeNil
}

这个想法是,如果任何操作返回nil,其余代码将一直持续到return语句,而不执行任何其他操作。

这也会在视觉上将代码中可能导致值设置为nil的所有部分分开