在Optional Double上调用方法以转换为String

时间:2019-02-01 18:15:02

标签: swift extension-methods optional

我写这篇文章是为了轻松将浮点数格式化为具有各种精度级别的字符串。

extension FloatingPoint {
    func str(_ precision: Int) -> String {
        return String(format: "%."+String(precision)+"f", self as! CVarArg)
    }
}

它非常适合浮点类型的非可选变量:

var myDouble: Double = 3.1415
var text = myDouble.str(2) // sets text = "3.14"

是否有办法使这样的内容适用于可选的Double

var myNilDouble: Double? = nil
var text = myNilDouble.str(2) // I'd like it to set text = "" 

我希望实现支持nil和非nil到字符串的转换。

2 个答案:

答案 0 :(得分:2)

您不是在Double上调用方法,而是在Optional<Double>上调用方法;完全不同的类型。因此,您需要该方法存在于Optional上:

extension Optional where Wrapped : FloatingPoint {
    func string(usingPrecision precision: Int) -> String {
        guard let double = self else { return "" }
        return double.str(precision)
    }
}

不过,我不喜欢这个界面;我认为决定发出空字符串不是Optional的工作。相反,我建议在String本身上使用一个Optional浮点数的初始化程序:

import Foundation

extension String {
    init<N : FloatingPoint>(_ value: N?, precision: Int) {
        guard let value = value else { self.init(); return }
        self.init(format: "%.\(precision)f", value as! CVarArg)
    }
}

现在您写

let value: Double? = nil
let text = String(value, precision: 2)    // ""

另一个选项是自由功能,再次使用Optional。 (当然,您也可以像Sulthan所说的那样,使呼叫者选择nil解决的问题。)

答案 1 :(得分:0)

最简单的解决方案是使用可选的链接和零合并:

var text = myNilDouble?.str(2) ?? ""

尽管您最终可能会多次重复此模式,但优点是您可以更好地控制nil方案,在某些情况下,您可能希望使用"(null)"作为默认值。