微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过Swift中的函数(或Init)传播可选项

有没有人(更好)的方式来做到这一点?

可以说我有一个可选的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.

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‘s float initialiser就是这样一个功能.

如果转换也返回一个可选项(例如将String转换为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) }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐