我有一个Swift可选类型,我希望将转换链接到它(map
)并最终将其传递给打印它的闭包。
我想避免解包(使用!
)可选类型,因为我不想执行闭包,除非我们在可选内容中有内容。
在Scala中,我们使用foreach
作为返回Unit的map
。
val oi = Option(2)
oi.map(_+1).foreach(println)
在Swift中我只得到增量(和转换为字符串)
let oi:Int? = 1
let oiplus = oi.map({$0 + 1}).map({String($0)})
// now we have "2"
现在,只有在可选项不是nil的情况下,如何才能将此项提交给print()
?
答案 0 :(得分:5)
我只是映射它
let oi: Int? = 1
let oiplus = oi.map{ $0 + 1 }.map { String($0) }
oiplus.map { print($0) }
对于产生副作用而言,映射并不好,但在Swift中foreach
没有Optional
。
这也会在Swift 2中产生unused result
警告。
如果语义(和警告)错误,您可以随时为foreach
定义自己的Optional
。这很简单:
extension Optional {
func forEach(f: Wrapped -> Void) {
switch self {
case .None: ()
case let .Some(w): f(w)
}
}
}
然后
let oi: Int? = 1
let oiplus = oi.map{ $0 + 1 }.map { String($0) }
oiplus.forEach { print($0) }
尽可能类似于scala。
答案 1 :(得分:2)
虽然我通常不建议使用map
副作用,但在这种情况下我认为它是最干净的Swift。
_ = oiplus.map{ print($0) }
现在有一个明确针对此问题的SequenceType.forEach
方法,但Optional
不是SequenceType
。你当然可以扩展Optional
来添加一个类似forEach
的方法(我可能在Swift中称它为apply
。)
值得注意的是,这只是避免了if-lit
,这几乎不再存在:
if let o = oiplus { print(o) }
但它确实没有像以下那样友好地链接:
_ = oi
.map { $0 + 1 }
.map { print($0) }
另见http://www.openradar.me/23247992,这基本上是加布里埃尔的答案。