1. 概述

在 Java 中,我们通常使用 printf 格式化字符串来对数字进行格式化输出。而在 Kotlin 中,我们也可以使用类似的方式,同时还可以结合 Kotlin 的语言特性,写出更简洁、优雅的代码。

本文将围绕如何在 Kotlin 中格式化浮点数展开,重点介绍几种常见方法,并通过单元测试验证其正确性。

2. 问题背景

在实际开发中,我们常常需要将 FloatDouble 类型的数字转换为字符串,并指定其精度(即小数点后保留几位)。例如我们定义了一个常量:

private const val PI = 3.141592653589793

我们希望将这个值格式化为字符串,并根据传入的精度返回不同的结果:

private const val EXPECTED_SCALE_0 = "3"
private const val EXPECTED_SCALE_2 = "3.14"
private const val EXPECTED_SCALE_4 = "3.1416"

接下来我们来看看如何实现这个功能。

3. 使用 Java 的 String.format 方法

Java 提供了 String.format 方法用于格式化字符串,使用的是 printf 风格的格式化语法。在 Kotlin 中调用也非常方便:

fun usingJavaStringFormat(input: Double, scale: Int) = String.format("%.${scale}f", input)

这个方法接收两个参数:要格式化的数字 input 和小数点后保留位数 scale

我们可以用单元测试来验证输出是否符合预期:

val out0 = usingJavaStringFormat(PI, 0)
assertThat(out0).isEqualTo(EXPECTED_SCALE_0)

val out2 = usingJavaStringFormat(PI, 2)
assertThat(out2).isEqualTo(EXPECTED_SCALE_2)

val out4 = usingJavaStringFormat(PI, 4)
assertThat(out4).isEqualTo(EXPECTED_SCALE_4)

✅ 测试通过,说明该方法是有效的。

⚠️ 注意:Java 的 String.format 不支持像 printf 那样使用 * 表示动态精度,因此我们需要手动拼接格式字符串,比如使用 Kotlin 的字符串模板 "%.${scale}f"

4. 使用 Kotlin 的 String.format 函数

Kotlin 在标准库中为 String 类型定义了一个扩展函数:

public inline fun String.format(vararg args: Any?): String = java.lang.String.format(this, *args)

本质上,它还是调用了 Java 的 String.format 方法,但使用起来更符合 Kotlin 的风格。

我们可以用它来实现一个更简洁的格式化函数:

fun usingKotlinStringFormat(input: Double, scale: Int) = "%.${scale}f".format(input)

同样,我们用测试来验证:

val out0 = usingKotlinStringFormat(PI, 0)
assertThat(out0).isEqualTo(EXPECTED_SCALE_0)

val out2 = usingKotlinStringFormat(PI, 2)
assertThat(out2).isEqualTo(EXPECTED_SCALE_2)

val out4 = usingKotlinStringFormat(PI, 4)
assertThat(out4).isEqualTo(EXPECTED_SCALE_4)

✅ 测试通过,说明 Kotlin 的 String.format 同样有效。

5. 为 Double 类创建扩展函数

Kotlin 的扩展函数特性允许我们为现有类添加新的方法。我们可以为 Double 类型添加一个格式化方法:

fun Double.format(scale: Int) = "%.${scale}f".format(this)

这样在使用时就非常自然:

val text = "Pi (${PI.format(4)}) is an important concept that appears in all aspects of math!"

我们也可以用测试来验证:

val out0 = PI.format(0)
assertThat(out0).isEqualTo(EXPECTED_SCALE_0)

val out2 = PI.format(2)
assertThat(out2).isEqualTo(EXPECTED_SCALE_2)

val out4 = PI.format(4)
assertThat(out4).isEqualTo(EXPECTED_SCALE_4)

✅ 测试通过,扩展函数方式也完全可用。

6. 小结

本文介绍了三种在 Kotlin 中格式化数字的方法:

方法 描述 优点 踩坑点
String.format(Java) 使用 Java 的 String.format 方法 简单直接,兼容性好 需手动拼接格式字符串
String.format(Kotlin) Kotlin 对 Java 方法的封装 更 Kotlin 风格,语法更简洁 本质还是 Java 的方法
扩展函数 on Double Double 类型添加 .format() 方法 代码更优雅,使用更流畅 仅适用于特定类型

✅ 三种方法各有适用场景,推荐根据项目风格和可读性选择使用。如果是 Kotlin 项目,推荐使用扩展函数方式,代码更简洁、语义更清晰。


原始标题:Number Formatting in Kotlin