简体   繁体   中英

Swift 3 Generic infix operator error

In the process of updating a project from Xcode 7 to 8, I'm facing a problem.

There is a generic infix operator which handles constraints on UIView s.

Here is the operator's definition:

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
}

now, upon using the operator, I'm getting an error I don't understand:

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

中缀运算符错误

I have tested with non-generic function too, it will still complain about the block's type.

Any idea?

PS: I'm not the original author of the code, I'm trying to updated the code for a PR and to change the syntax will impact too much code.

I was able to solve this problem by adding a return call at the end of the code block passed to the operator. It seems like Swift 3.0 compiler cannot infer code block to be a closure without return . As mentioned in the question's comments, the original operator should work fine with a new Swift 3.0 project, but converting the project from older Swift versions seems to break the operator somehow.

Any way This is the correct usage of the operator now and it works fine:

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

PS: I have been doing this fix before but I was getting a weird Segmentation Fault error 11 after a few of errors' been fixed and I wasn't aware of the reason. Turns out, Xcode could not handle some of the closure types and segmentation fault was happening. Adding return call to ALL places where the operator was being used solved the problem.

I would be happy to discuss the reason and a better solution with any interested developer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM