Swift如何将Decimal类型转换为String类型

19

如何在Swift中将Decimal转换为String

例如:

let de = Decimal(string: "123")

那么如何将 de 转换为字符串。


2
de.description 但你可能需要使用 as NSDecimalNumber 来访问 description(withLocale:)。你也可以使用 NumberFormatter,尽管它总是首先将小数转换为 double,但在大多数情况下这不是问题。 - Sulthan
十进制转字符串或字符串转十进制 - Subhojit Mandal
1
很遗憾,当从Decimal转换为String时,您无法同时支持本地化和精确小数。请参见https://openradar.appspot.com/29923468。 - Berik
4个回答

17

利用 Decimal 符合协议 CustomStringConvertible 的事实,我只需要这样做:

let decimalString = "\(de)"

5
字符串插值也可行,但我更喜欢使用String(describing: de),因为这是Apple推荐的方法之一。当处理符合CustomStringConvertible协议的类型时,"使用String(describing:)初始化器是将任何类型的实例转换为字符串的首选方式。" - Guillaume Algis
不,这是错误的!CustomStringConvertible 是一个调试 API,你不应该将其用于序列化。 - Isaaс Weisberg
嗨,@IsaaсWeisberg,你在哪里看到CustomStringConvertible是一个调试API的? - Marco
也许 @IsaaсWeisberg 你指的是另一个协议?CustomDebugStringConvertible - Marco

8

将其转换为NSDecimalNumber并使用stringValue。

NSDecimalNumber(decimal: de).stringValue


那似乎是一种非常低效的方法。String(describing: de) 似乎是更好的方法,或者像 @Marco 回答的那样使用字符串插值。 - Guillaume Algis
这是正确的方法,因为String(describing:)是一个调试API。 - Isaaс Weisberg

-3
在Swift 3及以上版本中尝试这样做。
extension Formatter {
    static let stringFormatters: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .none
        return formatter
    }()
}

extension Decimal {
    var formattedString: String {
        return Formatter.stringFormatters.string(for: self) ?? ""
    }
}

你可以这样展示

label.text = someDecimal.formattedString

1
NumberFormatter 内部使用双精度浮点数。该扩展不会返回有效的十进制表示形式。 - Berik
我认为应该用string(from:), 而不是 string(for:) - ma11hew28

-3
使用NSNumberFormatter来解析您的输入。将其generatesDecimalNumbers属性设置为true:
let formatter = NumberFormatter()
formatter.generatesDecimalNumbers = true

以下是如何使用它的方法,如果您想在字符串无法解析时返回0:

func decimal(with string: String) -> NSDecimalNumber {
    return formatter.number(from: string) as? NSDecimalNumber ?? 0
}

decimal(with: "80.00")

// Result: 80 as an NSDecimalNumber

默认情况下,格式化程序将查看设备的区域设置以确定小数点。您应该保持这种方式。为了举例说明,我将强制使用法语区域设置:

// DON'T DO THIS. Just an example of behavior in a French locale.
formatter.locale = Locale(identifier: "fr-FR")

decimal(with: "80,00")
// Result: 80

decimal(with: "80.00")
// Result: 0

如果您真的想始終使用逗號作為小數分隔符,可以設置decimalSeparator屬性:

formatter.decimalSeparator = ","

1
NumberFormatter在内部使用双精度而不是十进制精度,即使generateDecimalNumbers设置为true也是如此。 - Berik
该问题询问如何将Decimal转换为String,而不是如何将String转换为Decimal。对于前者,您不需要将formatter.generatesDecimalNumbers设置为true,并且应调用formatter.string(from: number)而不是formatter.number(from: string)。但是,@Berik声称这对于每个可能的Decimal值都无法正常工作。 - ma11hew28
我一定是看错了题目。 - Berik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接