有没有人(更好)的方法来做到这一点?
可以说我有一个可选的Float
let f: Float? = 2
现在我想将其转换为Double
let d = Double(f) //fail
这显然会失败,但是有没有办法像通过计算变量那样通过函数链接可选项?我现在正在做的是这样的:
extension Float { var double: Double { return Double(self) } } let d: Double? = f?.double
但是我真的不喜欢将强制转换作为计算变量。
我考虑使用的另一个选项是:
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)
我意识到我可以保护’f’的值来解开它。但是,在许多情况下,可选值将是返回可选函数的参数。这导致防护中的中间值。如本例所示:
func foo(_ a: String?) throws -> Float { guard let a = a, let intermediate = Float(a) else { throw.something } return intermediate }
在这里,从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 }
我不想重写频繁初始化的可选版本。
任何想法将不胜感激。谢谢!
您可以简单地使用Optional的map(_:)方法,该方法将返回包装的值,如果该值不为nil,则应用给定的转换,否则将返回nil。
Optional
map(_:)
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) }
正如您在下面的评论中指出的那样,也可以这样表示:
let d = f.map(Double.init)
这是因为在这种情况下map(_:)期望类型的转换函数(Float) -> Double,而Doublefloat初始化程序 就是 这样的函数。
(Float) -> Double
Double
如果变换也返回一个可选的(例如转换一个当为String一个Int),就可以使用flatMap(_:),其只是传播的nil变换结果返回给调用者:
String
Int
flatMap(_:)
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) }