【问题标题】:Simulating macros with return in Swift在 Swift 中使用 return 模拟宏
【发布时间】:2015-02-14 00:50:21
【问题描述】:

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

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

它可以用来测试一个函数是否返回了nil(表示错误),如果是这样,调用者可以简单地返回nil——将错误传播到堆栈上。我正在编写一个解析器,这种模式经常发生。例如

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

- (id)callee {
    ...
}

不幸的是,在转向 swift 之后,宏就消失了。函数(带有@autoclosure)将替换它们,但在这种情况下不是。现在我的代码中到处都是相同的if 检查。

有在 Swift 中复制相同内容的想法吗?

【问题讨论】:

  • if nil == z { return nil } 真的更糟吗?对我来说,这比您可以秘密退出方法的宏要清楚得多。
  • 我也缺少这个功能。 @drewag 需要输入更多内容,理想情况下,我希望能够在检查后将z 用作常量,而不是需要展开的可选选项。现在我正在使用像if let z = self.callee() { ... 这样的通用模式,但是我必须缩进整个函数的其余部分:/
  • @pejalo 如果您不想缩进其余代码,您可以随时使用保护语句
  • 谢谢@drewag 我不知道guard。后面加上所需的else { return } 仍然有点冗长,但比缩进 IMO 更好。

标签: objective-c swift macros


【解决方案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 的所有部分

【讨论】:

  • 不完全是我所追求的,但非常有趣的解决方案,感谢!
猜你喜欢
  • 1970-01-01
  • 2013-12-25
  • 2014-08-02
  • 2015-09-07
  • 1970-01-01
  • 2010-09-16
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多