有没有人(更好)的方式来做到这一点?
可以说我有一个可选的Float
let f: Float? = 2
Run Code Online (Sandbox Code Playgroud)
现在我想将它转换为Double
let d = Double(f) //fail
Run Code Online (Sandbox Code Playgroud)
这显然会失败,但有没有办法通过函数链接可选的计算变量?我现在在做的是:
extension Float {
var double: Double { return Double(self) }
}
let d: Double? = f?.double
Run Code Online (Sandbox Code Playgroud)
但我真的不喜欢将演员表作为计算变量.
我考虑使用的另一个选项是:
public func optionalize<A,B>(_ ? : @escaping (A) -> B) -> (A?) -> B? {
return { (a) in
guard let a = a else { return nil }
return ?(a)
}
}
let d: Double? = optionalize(Double.init)(f)
Run Code Online (Sandbox Code Playgroud)
我意识到我可以保护'f'的价值来解开它.但是,在许多情况下,可选值将是返回可选项的函数的参数.这导致防护中的中间值.如下例所示:
func foo(_ a: String?) throws -> Float {
guard
let a = a,
let intermediate = Float(a)
else { throw.something }
return intermediate
}
Run Code Online (Sandbox Code Playgroud)
这里从String到Float的转换也可能失败.至少使用计算变量,这个foo函数更清晰一点
extension String {
var float: Float? { return Float(self) }
}
func foo(_ a: String?) throws -> Float {
guard
let a = a?.float
else { throw.something }
return a
}
Run Code Online (Sandbox Code Playgroud)
我不想重写频繁插入的可选版本.
任何想法将不胜感激.谢谢!
您可以简单地使用Optionalsmap(_:)方法,如果它非零,它将返回应用给定转换的包装值,否则它将返回nil。
let f : Float? = 2
// If f is non-nil, return the result from the wrapped value passed to Double(_:),
// else return nil.
let d = f.map { Double($0) }
Run Code Online (Sandbox Code Playgroud)
正如您在下面的评论中指出的那样,也可以说是:
let d = f.map(Double.init)
Run Code Online (Sandbox Code Playgroud)
这是因为在这种情况下map(_:)需要一个类型的转换函数(Float) -> Double,并且Double的 float 初始值设定项 就是这样一个函数。
如果转换还返回一个可选值(例如将 an 转换String为 a时Int),您可以使用flatMap(_:),它只是将nil转换结果传播回调用者:
let s : String? = "3"
// If s is non-nil, return the result from the wrapped value being passed to the Int(_:)
// initialiser. If s is nil, or Int($0) returns nil, return nil.
let i = s.flatMap { Int($0) }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
163 次 |
| 最近记录: |