【问题标题】:Swift 3 Generic infix operator errorSwift 3 通用中缀运算符错误
【发布时间】:2016-08-29 10:44:17
【问题描述】:

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

有一个通用的infix 操作符处理UIViews 上的约束。

这里是操作符的定义:

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
      }
    }

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

有什么想法吗?

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

【问题讨论】:

  • 代码不多,你可以在任何地方轻松验证。我以为我已经提供了足够的证据。你还需要什么?
  • 我已经尝试(但失败)在 Xcode 8 beta 6 中重现这个(我假设 this 是你指的 GitHub 项目?)。有关它的编译示例,请参阅this gist。也许尝试清理你的构建文件夹?
  • 是的,没错。我已经清理并删除了派生数据和所有内容。我已经测试了你的要点,它按预期工作,但在主项目中。我猜是设置搞砸了。我现在必须调查项目的构建设置。感谢您的帮助。

标签: ios generics operator-overloading swift3


【解决方案1】:

我能够通过在传递给操作员的代码块末尾添加一个return 调用来解决这个问题。如果没有return,似乎 Swift 3.0 编译器无法将代码块推断为闭包。正如问题的 cmets 中所述,原始运算符应该可以在新的 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 调用添加到所有使用操作员的地方解决了问题。

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

【讨论】:

    猜你喜欢
    • 2018-01-18
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    相关资源
    最近更新 更多