崩溃nil可选

我做了一个新的操作符,只有当值不为零时才将值赋给一个目标,否则什么都不做。 基本上它是一个合成糖, if let foo = foo { faa = foo }

 infix operator =? {} func =?<T>(inout lhs: T, rhs: T?) { if let rhs = rhs { lhs = rhs } } func =?<T>(inout lhs: T?, rhs: T?) { if let rhs = rhs { lhs = rhs } } 

这样我可以保存一些input:

 // instead this: if let x = maybeX { z = x } // I can do this: z =? x 

我的问题是,当我到达执行线( z =? x )时,甚至在进入实现func之前崩溃,例外:

 fatal error: unexpectedly found nil while unwrapping an Optional value 

看来Swift试图强制unwrap x甚至当实现接受T?

有任何想法吗?

这似乎是我的错误…我正在使用foo.z = ...哪里foo是一个无UIImageView! 从n dam的意见…

我会愉快地改变我的实现与@RMenkebuild议之后没有合并的运算符,但据我所知,这将导致一个冗余的行动,设置z为z当z为零…例如:

 var z = someFoo() var x: Int? = nil z = x ?? z // will this re-write z's reference to z again or simply do nothing? 

@MartinR提出了一个重要的评论:

如果一个运算符(或者函数)接受一个inout参数,那么即使你没有在运算符内部赋值,属性设置器也会被返回。

为了解决这个问题,我做了下面的扩展,作为_ = foo.map...方法的更清晰的版本:

 extension Optional { public func use<U>(@noescape f: (Wrapped) throws -> U) rethrows { _ = try self.map(f) } } //then: x.use{ z = $0 } 

这可能是更好的,因为当x为零时它不会调用z的setter,但它是最清洁/最清晰的方式吗?

您的操作员工作,但你应该已经使用链式选项:foo?.z = …

但是,当foo为零时,这会给你另一种错误,你可以通过添加来修复

 func =?<T>(lhs: T??, rhs: T?) -> () {} 

运算符的这个“什么都不做”版本吸收了当传递一个可选链,在最后一个成员之前有一个零的时候得到的不可变参数版本。