Golang strconv.AppendFloat
最后修改于 2025 年 4 月 20 日
本教程将解释如何在 Go 中使用 strconv.AppendFloat
函数。我们将通过实际示例介绍浮点数到字符串转换的基础知识。
strconv.AppendFloat
函数将浮点数转换为字符串并将其附加到字节切片。它提供对格式的精确控制。
AppendFloat 对于构建包含浮点数值的字符串非常高效,因为它通过直接附加到现有字节切片来避免分配。它支持各种格式选项和精度。
基本的 strconv.AppendFloat 示例
strconv.AppendFloat
最简单的用法是将浮点数转换为字符串并将其附加到字节切片。这里我们展示了基本用法。
package main import ( "fmt" "strconv" ) func main() { buf := []byte("Value: ") f := 3.14159 buf = strconv.AppendFloat(buf, f, 'f', 2, 64) fmt.Println(string(buf)) }
我们从包含 "Value: " 的字节切片开始,然后附加一个格式化的浮点数。'f' 格式指定了定点表示法,并带有 2 位小数。
不同的格式选项
strconv.AppendFloat
支持多种格式选项。此示例演示了 'f'、'e'、'g' 和 'b' 格式。
package main import ( "fmt" "strconv" ) func main() { f := 1234.5678 fmt.Println(string(strconv.AppendFloat([]byte{}, f, 'f', 2, 64))) fmt.Println(string(strconv.AppendFloat([]byte{}, f, 'e', 2, 64))) fmt.Println(string(strconv.AppendFloat([]byte{}, f, 'g', 4, 64))) fmt.Println(string(strconv.AppendFloat([]byte{}, f, 'b', -1, 64))) }
每种格式会产生不同的输出:'f' 用于定点数,'e' 用于科学计数法,'g' 用于紧凑表示,'b' 用于二进制指数。
控制精度
精度参数控制显示多少位数。此示例显示了同一浮点数的不同精度值。
package main import ( "fmt" "strconv" ) func main() { f := 3.141592653589793 for _, prec := range []int{0, 2, 4, 6, 8} { buf := strconv.AppendFloat([]byte("π ≈ "), f, 'f', prec, 64) fmt.Println(string(buf)) } }
我们以递增的精度级别展示 π。更高的精度值会在输出中显示更多的小数位数。
构建复杂字符串
AppendFloat
有助于高效地构建复杂字符串。此示例创建了一个格式化的测量字符串。
package main import ( "fmt" "strconv" ) func main() { temp := 23.456 humidity := 45.678 buf := []byte("Current conditions: ") buf = strconv.AppendFloat(buf, temp, 'f', 1, 64) buf = append(buf, "°C, "...) buf = strconv.AppendFloat(buf, humidity, 'f', 1, 64) buf = append(buf, "% humidity"...) fmt.Println(string(buf)) }
我们通过附加多个浮点数值和文本来构建天气报告字符串。与字符串拼接相比,这种方法可以最大限度地减少分配。
处理特殊的浮点数值
AppendFloat
可以正确处理 NaN 和无穷大等特殊浮点数值。此示例演示了它们的字符串表示。
package main import ( "fmt" "math" "strconv" ) func main() { values := []float64{ math.NaN(), math.Inf(1), math.Inf(-1), 0.0, } for _, v := range values { buf := strconv.AppendFloat([]byte{}, v, 'g', -1, 64) fmt.Println(string(buf)) } }
特殊浮点数值会被转换为它们的字符串表示:“NaN”表示非数字,“+Inf”表示正无穷大,“-Inf”表示负无穷大。
性能比较
此示例比较了 AppendFloat
与 fmt.Sprintf
在浮点数到字符串转换性能上的差异。
package main import ( "fmt" "strconv" "time" ) func main() { const iterations = 1000000 f := 123.456789 // Benchmark AppendFloat start := time.Now() buf := make([]byte, 0, 32) for i := 0; i < iterations; i++ { buf = strconv.AppendFloat(buf[:0], f, 'f', 2, 64) } fmt.Println("AppendFloat duration:", time.Since(start)) // Benchmark Sprintf start = time.Now() for i := 0; i < iterations; i++ { _ = fmt.Sprintf("%.2f", f) } fmt.Println("Sprintf duration:", time.Since(start)) }
AppendFloat
在浮点数格式化方面比 fmt.Sprintf
快得多,尤其是在性能关键的代码中构建字符串时。
实际示例:CSV 生成
这个实际示例演示了如何使用 AppendFloat
高效地生成包含浮点数值的 CSV 数据。
package main import ( "fmt" "strconv" ) type Measurement struct { Time float64 Value float64 } func main() { data := []Measurement{ {0.0, 12.3}, {1.0, 15.6}, {2.0, 18.2}, {3.0, 22.1}, } var csv []byte csv = append(csv, "time,value\n"...) for _, m := range data { csv = strconv.AppendFloat(csv, m.Time, 'f', 1, 64) csv = append(csv, ',') csv = strconv.AppendFloat(csv, m.Value, 'f', 1, 64) csv = append(csv, '\n') } fmt.Println(string(csv)) }
我们通过将浮点数值直接附加到字节切片来生成 CSV 输出。这种方法在内存方面效率很高,并避免了不必要的字符串分配。
来源
本教程通过各种场景下的浮点数到字符串转换的实际示例,涵盖了 Go 中的 strconv.AppendFloat
函数。