将一个对象转换成对应的字符串对象的过程称之为格式化(format)。在仓颉中,std.convert包为Float32、Float64、Int32、Int64、UInt32、UInt64等类型扩展实现了format成员函数。在导入std.convert包后,再执行这些对象的format成员函数,即可将对象“转换”成对应的字符串表达形式。

  而上述format成员函数,包含了一个名为fmt的字符串类型的参数,用于指定转换格式。

1. 简单格式化示例

  下述示例将浮点数对象pi按指定格式转换成字符串并打印至屏幕。

1
2
3
4
5
6
7
8
9
package StrFormat
import std.convert //导入std标准库下的format包

main(): Int64 {
let pi:Float64 = 3.141592653589793238462643383279
let s1 = pi.format(".4"); let s2 = pi.format("+20.10")
println(s1); print(s2) //s1, s2均为String类型
return 0
}

上述代码的执行结果为:

1
2
3.1416
+3.1415926536

▶第2行:导入std标准模块下的convert(格式化)包。程序第6行所使用的格式化函数是由该包定义的。

▶第5行:定义圆周率不可变变量pi,为尽可能提高存储精度,这里使用了Float64类型。

▶第6行:在导入了std.convert之后,pi作为Float64类型的对象,便拥有了成员函数format。

  如执行结果第1行所示,pi.format(“.4”)将pi格式化,生成了将pi保留4位小数的字符串“3.1416”。format函数的参数”.4”为一个字符串字面量,它表明转换格式为“保留4位小数”。不难看出,3.1415926在格式化保留4位小数的过程中被四舍五入,变成了3.1416。

  如执行结果第2行所示,pi.format(“+20.10”)将pi格式化为显示正负号(+)、包含20个字符、保留10位小数、右对齐的字符串,不足部分使用空格补齐。

  请注意,pi.format(x)只是根据pi值以及格式串x的要求生成并返回一个新的字符串对象,浮点数对象pi在函数执行前后类型和值都保持不变

▶第7行:将格式化结果字符串s1和s1通过println和print函数打印至屏幕。

2. 格式化参数

  根据仓颉文档,format(fmt:String):String函数的fmt参数用于指定格式化参数,这些参数用于规定转换结果的宽度、对齐方式、精度等信息。格式化参数fmt的语法格式为:

[flags][width][.precision][specifier]

  其中,方括号表示这些字段为可选,即格式化参数并不需要完整包含上述4个字段。

3. flags

  flags字段可以包含”-“、”+”、”#”、“0”四个字符中的1个或多个。

  • “-“适用于Int、UInt、Float等类型,表示左对齐。
1
2
3
4
5
6
7
8
9
10
11
12
package Alignment
import std.convert

main(): Int64 {
var c:Int32 = -17
let s1 = c.format("-20") //20个字符,左对齐
println(s1)

let s2 = c.format("20") //20个字符,默认右对齐
print(s2)
return 0
}

上述程序的执行结果为:

1
2
-17
-17

▶第6行:格式化参数”-20”中的”-“属于flags字段,表示转换结果应为左对齐;”20”则属于width字段,表示结果字符串应包含20个字符,不足部分用空格补齐。

▶第9行:格式化参数未要求左对齐,默认右对齐。如执行结果第2行所见,format成员函数通过在左侧补充空格的方式满足20的宽度要求。

  • “+”适用于Int、UInt、Float,表示对正数输出+号
1
2
3
4
5
6
7
8
9
10
11
12
13
package Plus
import std.convert

main(): Int64 {
var v1:Float32 = 7.1287
let s1 = v1.format("+") //给正值使用+,结果中会出现+号
println(s1)

var v2:Float32 = -7.1287
let s2 = v2.format("+") //给负值使用+
print(s2)
return 0
}

上述程序的执行结果为:

1
2
+7.128700
-7.128700

  如执行结果第2行所见,当给负值使用”+”时,于转换结果不构成影响。

  • “#” - 为转换结果添加进制符号

  具体地,为二进制结果补充0b或者0B,为16进制结果补充0x或者0X,为8进制结果补充0o或者0O。当输出结果为10进制时,不起作用。该符号预期与specifier中的进制符号x,b等联合使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package Sharp
import std.convert

main(): Int64 {
var v = 125
println(v.format("#x"))
println(v.format("x")) //x为specifier,意为16进制

println(v.format("#B"))
println(v.format("B")) //B为specifier,意为2进制

//未指定进制,即为10进制,#号不起作用
print(v.format("#"))
return 0
}

上述程序的执行结果为:

1
2
3
4
5
0x7d                   //x导致了7d, #号附加了0x
7d //没有#号,就没有0x
0B1111101 //B导致2进制结果,#号附加了0B
1111101 //没有#号,就没有0B
125 //对于10进制,#号不起作用
  • “0”适用于Int, UInt和Float,用于在空位补0
1
2
3
4
5
6
7
8
9
package ZeroLeading
import std.convert

main(): Int64 {
var v = 72.6386654
println(v.format("020")) //20个字符,不足前端补0
print(v.format("20")) //20个字符,不足前端补空格
return 0
}

上述程序的执行结果为:

1
2
0000000000072.638665
72.638665

4. width - 宽度

  v.format(“20”)中的20即为宽度。宽度应为正整数,适用于Int,UInt,Float等类型。宽度前有”-“表示左对齐,否则右对齐。

1
2
3
4
5
6
7
8
9
package Width
import std.convert

main(): Int64 {
var v = 123456
println(v.format("20")) //自身占6个字符,前方补了14个空格
print(v.format("+20")) //连同+号占7个字符,前方补了13个空格
return 0
}

上述程序的执行结果为:

1
2
 123456
+123456

5. precision - 精度

  精度常用于指定浮点数小数点后的数字位数,如果不指定,则默认输出6位小数。

1
2
3
4
5
6
7
8
9
10
package Precision
import std.convert

main(): Int64 {
var v:Float64 = 12345.678987654321
println(v.format(".3")) //3位小数,四舍五入
println(v.format(".5")) //5位小数,四舍五入
print(v.format(".0")) //0位小数,四舍五入
return 0
}

上述程序的执行结果为:

1
2
3
12345.679
12345.67899
12346

6. specifier

  • b, B,o, O, x, X用于指定进制,适用于Int和UInt类型

b为小写2进制,B为大写2进制; o为小写8进制,O为大写8进制; x为小写16进制,X为大写16进制; 默认10进制。

如前所述,上述进制符号可与flags中的”#”号配合使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
package Base
import std.convert

main(): Int64 {
var v = 4571
println(v.format("b"))
println(v.format("B"))
println(v.format("o"))
println(v.format("O"))
println(v.format("x"))
print(v.format("X"))
return 0
}

上述程序的执行结果为:

1
2
3
4
5
6
1000111011011
1000111011011
10733
10733
11db
11DB
  • e, E,g, G适用于Float类型

  e表示小写的科学计数法,E表示大写的科学计数法; g或G源于general(常规),表示让仓颉在科学计数法和普通10进制计数法中自动选择较为精单的表达方式。

1
2
3
4
5
6
7
8
9
10
11
12
package Scientific
import std.convert

main(): Int64 {
var a = 1234.5678987654321
println(a.format("e"))
println(a.format(".3E"))
println(a.format("g")) //自适应:常规10进制
var b = 228989289.1234234
print(b.format(".2G")) //自适应:科学计数法
return 0
}

上述程序的执行结果为:

1
2
3
4
1.234568e+03    //e
1.235E+03 //E
1234.57 //g
2.3E+08 //.2G