Swift断言:无论如何都可以在字符串中打印变量

10

背景:在 Objective-C 中,我会创建一个包含调试信息的断言:

NSAssert(poetCount > 5, "Expected poetCount > 5; Actual: %d", poetCount);

不过,在Swift中,全局的assert函数似乎不允许这样做,因为消息参数是一个StaticString类型。所以我不能这样做:

assert(NSFileManager.defaultManager().fileExistsAtPath(fullpath), 
"Expected: File to Exist @ \(fullpath)")

问题: 是否有可替代的assert函数,它不需要静态字符串?或者如果我想要添加额外信息以使调试更容易,是否应该继续使用NSAssert


如果您将“Expected......”部分替换为字符串对象,会发生什么?抱歉,在Windows上无法测试。 - Lord Zsolt
@LordZsolt 如果我写 let assertString = "Expect: sectionIndex > 0; Actual \(sectionIndex)"; assert(sectionIndex > 0, assertString) 我会得到这个错误:"找不到接受提供的参数的'assert'的重载" - Tobias
1
我不知道苹果什么时候改变了这个,但是assert现在可以处理字符串插值。 - Tobias
2个回答

10

因为StaticString参数的缘故,我认为你目前无法实现。我试着用一个let来设置消息字符串,但是似乎连变量都不能放进去,必须是用引号括起来的StaticString。

值得一提的是,苹果的示范代码也采用了同样的模式:

assert(listItems && listItems!.count == 1, "There must be exactly one moved item.")

感谢您的回复。 - Tobias

3

你可以使用String编写自己的assert版本,这是一个示例:

func assert(condition: @autoclosure () -> Bool, _ message: String = "") {
    #if DEBUG
        if !condition() {
            println(message);
                abort()
        }
    #endif 
}

或者附加调试信息:

func assert(condition: @autoclosure () -> Bool, _ message: String = "", file: String = __FILE__, line: Int = __LINE__) {
    #if DEBUG
        if !condition() {
            println("assertion failed at \(file):\(line): \(message)");
                abort()
        }
    #endif
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接