Swift 3 Generic中缀操作符错误

时间:2016-08-29 10:44:18

标签: ios generics operator-overloading swift3

在将项目从Xcode 7更新到8的过程中,我遇到了一个问题。

有一个通用的infix运算符可以处理UIView的约束。

以下是运营商的定义:

precedencegroup constPrecedence {
  associativity: left
  higherThan: AssignmentPrecedence
}

infix operator >>>- : constPrecedence

@discardableResult
func >>>- <T: UIView> (left: (T, T), block: (inout ConstraintInfo) -> ()) -> NSLayoutConstraint {
  var info = ConstraintInfo()
  block(&info)
  info.secondAttribute = info.secondAttribute == .notAnAttribute ? info.attribute : info.secondAttribute

  let constraint = NSLayoutConstraint(item: left.1,
                                      attribute: info.attribute,
                                      relatedBy: info.relation,
                                      toItem: left.0,
                                      attribute: info.secondAttribute,
                                      multiplier: 1,
                                      constant: info.constant)
  constraint.identifier = info.identifier
  left.0.addConstraint(constraint)
  return constraint
}

现在,在使用运算符时,我收到一个我不明白的错误:

   for attribute: NSLayoutAttribute in [.left, .right, .top, .bottom] {
      (view, self) >>>- {
        $0.attribute = attribute
      }
    }

infix operator error

我也测试了非泛型函数,它仍然会抱怨块的类型。

有什么想法吗?

P.S。:我不是代码的原作者,我正在尝试更新PR的代码,并且更改语法会影响太多的代码。

1 个答案:

答案 0 :(得分:0)

我能够通过在传递给运算符的代码块末尾添加return调用来解决此问题。看起来Swift 3.0编译器不能将代码块推断为没有return的闭包。正如问题的评论中所提到的,原始运算符应该可以正常使用新的Swift 3.0项目,但是从旧的Swift版本转换项目似乎会以某种方式打破运算符。

任何方式现在这是运算符的正确用法,它可以正常工作:

 for attribute: NSLayoutAttribute in [.left, .right, .top, .bottom] {
      (view, self) >>>- {
        $0.attribute = attribute
        return
      }
    }

P.S。:我之前一直在修这个问题,但是在发生一些错误之后我得到了一个奇怪的Segmentation Fault error 11。已修好,我不知道原因。事实证明,Xcode无法处理某些闭包类型并且发生了分段错误。将return调用添加到正在使用运算符的所有位置可以解决问题。

我很乐意与任何感兴趣的开发者讨论原因和更好的解决方案。