Is there a clean way to handle assignment expressions inside condiionals in Swift 3?

时间:2017-04-06 16:52:04

标签: swift

I am new to Swift and am in the process of porting the jay parser generator to output a Swift parser. In the parser skeleton file I've found constructs that use the result of an assignment expression inside a conditional. E.g. ...

if ((yyN = yySindex[yyStates[yyTop]]) != 0 && 
    (yyN += yyErrorCode) >= 0 && 
     yyN < yyTable.Length && 
     yyCheck[yyN] == yyErrorCode) { ... }

Note in particular the (yyN += yyErrorCode) >= 0 expression

Since Swift doesn't allow assignment expressions to return a value is there an efficient way to code this type of construct in Swift?

2 个答案:

答案 0 :(得分:1)

  

由于Swift不允许赋值表达式返回值   有一种在Swift中编码这种类型的构造的有效方法吗?

是:将分配与条件分开,并将其分解为更小的组件(请参阅例如@tuple_cat:s answer)。

(不要这样做)

为了它的乐趣,并简要介绍一下Swift的一些技术可能性; Swift 可以用于模拟如上所述的重度聚类条件评估。为了解决你的例子(以一种非常非干净的方式),你可以使用内联yyN - 捕获和Bool - 返回闭包来进一步增加不可读性:

if ({_ in yyN = yySindex[yyStates[yyTop]]; return yyN != 0}()) && 
   ({_ in yyN += yyErrorCode; return yyN != 0}()) && 
   yyN < yyTable.Length && 
   yyCheck[yyN] == yyErrorCode { 
   /* ... */ 
}

Swift还允许定义自定义运算符,因此我们可以构造赋值运算符,只调用它们的默认版本(副作用),但返回赋值语句中的赋值。例如。如果yyN的类型为Int

// some C++ style assignment operators
infix operator ^=: AssignmentPrecedence
infix operator ^+=: AssignmentPrecedence
extension Int {
    static func ^= (lhs: inout Int, rhs: Int) -> Int {
        lhs = rhs
        return rhs
    }
    static func ^+= (lhs: inout Int, rhs: Int) -> Int {
        lhs += rhs
        return lhs
    }
}

if ((yyN ^= yySindex[yyStates[yyTop]]) != 0 &&
    (yyN ^+= yyErrorCode) >= 0 &&
    yyN < yyTable.Length &&
    yyCheck[yyN] == yyErrorCode) {
    /* ... */
}

答案 1 :(得分:0)

Yes:

yyN = yySindex[yyStates[yyTop]]
if yyN != 0 {
    yyN += yyErrorCode
    if yyN >= 0 && yyN < yyTable.Length && yyCheck[yyN] == yyErrorCode {
        // …
    }
}