简体   繁体   中英

Format Int64 with thousand separators

I have used below code successfully to format Int with thousand separators. However my current project required Int64 to be formatted the same way and it throws error 'Int64' is not convertible to 'NSNumber'

var numberFormatter: NSNumberFormatter {
    let formattedNumber = NSNumberFormatter()
    formattedNumber.numberStyle = .DecimalStyle
    formattedNumber.maximumFractionDigits = 0
    return formattedNumber
}

You mean when you call numberFormatter.stringFromNumber(12345678) after the above code, like this?

let i64: Int64 = 1234567890
numberFormatter.stringFromNumber(i64)

Doesn't look like Swift will cast from an Int64 to an NSNumber :

let i = 1234567890
let n = i as NSNumber  // OK
numberFormatter.stringFromNumber(i)  // Also OK

// Compiler error: 'Int64' is not convertible to 'NSNumber'
let n64 = i64 as NSNumber
// so the implicit conversion will also fail:
numberFormatter.stringFromNumber(i64)

This is a bit confounding, since Swift Int s are themselves usually the same size as Int64 s.

You can work around it by constructing an NSNumber by hand:

let n64 = NSNumber(longLong: i64)

BTW beware that var trick: it's nice that it encapsulates all the relevant code for creating numberFormatter , but that code will run afresh every time you use it. As an alternative you could do this:

let numberFormatter: NSNumberFormatter = {
    let formattedNumber = NSNumberFormatter()
    formattedNumber.numberStyle = .DecimalStyle
    formattedNumber.maximumFractionDigits = 0
    return formattedNumber
}()

If it's a property in a struct/class, you could also make it a lazy var which has the added benefit of only being running if the variable is used, like your var , but only once.

struct Thing {
    lazy var numberFormatter: NSNumberFormatter = {
        println("blah")
        let formattedNumber = NSNumberFormatter()
        formattedNumber.numberStyle = .DecimalStyle
        formattedNumber.maximumFractionDigits = 0
        return formattedNumber
    }()
}
extension Formatter {
    static let decimalNumber: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter
    }()
}

extension Numeric {
    var formatted: String { Formatter.decimalNumber.string(for: self) ?? "" }
}

let x: Int64 = 1000000
x.formatted   // "1,000,000"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM