Swift 泛型扩展到多个 类

Swift generics extension to multiple classes

所以我想为 NSNumber、Int、Double 和 Float 添加一个通用扩展,将值转换为格式化的字符串。

我首先创建了一个自定义协议:

protocol MyFormatConvertible {
    var toMyFormat: String { get }
}
extension NSNumber: MyFormatConvertible {}
extension Double: MyFormatConvertible {}
extension Float: MyFormatConvertible {}
extension Int: MyFormatConvertible {}

现在我正在尝试将格式添加到扩展名中:

extension MyFormatConvertible {
    public var toMyFormat: String {
        let numberValue = NSNumber(value:self)
    ....

但这似乎不起作用,因为我收到错误消息:

Cannot invoke initializer for type 'NSNumber' with an argument list of type '(value: Self)'

关于如何解决这个问题的任何提示?

您可以简单地使用 String(describing: self) 来实现。

protocol MyFormatConvertible {
    var toMyFormat: String { get }
}

extension MyFormatConvertible {

    var toMyFormat: String {
      return String(describing: self)
   }
}

extension NSNumber: MyFormatConvertible {}
extension Double: MyFormatConvertible {}
extension Float: MyFormatConvertible {}
extension Int: MyFormatConvertible {}

print(1.toMyFormat)
print(1.2.toMyFormat)
print(1.234.toMyFormat)
print(NSNumber(value: 1.23456).toMyFormat)

NSNumber(value:) 有多个重载用于各种 数字类型,但没有通用的 NSNumber(value:) 构造函数。

一个可能的解决方法是使用

func string(for obj: Any?) -> String?

NumberFormatter 的 "abstract" 超类 Formatter 的函数,它接受任何类型的参数(但可能 return nil):

protocol MyFormatConvertible {
    var toMyFormat: String { get }
}

extension MyFormatConvertible {
    var toMyFormat: String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .spellOut // <-- Just for demonstration purposes!!
        return formatter.string(for: self) ?? "\(self)"
    }
}

extension NSNumber: MyFormatConvertible {}
extension Double: MyFormatConvertible {}
extension Float: MyFormatConvertible {}
extension Int: MyFormatConvertible {}

print(123.toMyFormat) // one hundred twenty-three
print(Float.pi.toMyFormat) // three point one four one five nine two five zero two five nine three nine nine