今天我们继续来学习Java和Go语言在数字和字符串转换方面的不同的特性和用法。本文将比较Java语言和Go语言在数字和字符串转换方面的异同,以帮助大家更好地理解它们。
Java是一种面向对象的编程语言,拥有丰富的类库和框架。数字转字符串就异常简单。
直接调用其toString()方法来转换为字符串,简直不要太方便
Integer integer = 666;
String str = integer.toString();
而即使是基本数据类型也可以调用Integer的静态方法
int num = 666;
String str = Integer.toString(num);
这方法就更多了,除了上述调用各自包装类型的toString(num)方法,还有
//1 String.valueOf();
int num = 666;
String str = String.valueOf(num);
//2.String的format方法
int num = 666;
String str = String.format("%d", num);
//3. 甚至可以直接拼接
int num = 666;
String str = "" + num;
但是到了Go语言的数字转字符串就复杂一些。具体来说,可以使用strconv.FormatXxxxx()函数将数字转换为字符串,事先说好使用它就仿佛带上了痛苦面具。
先来看看int家族,我们可以用strconv.FormatInt()方法,不过要注意参数,第一被转化的数字必须是int64类型,第二我们要选择转换的进制。源码如下
// FormatInt returns the string representation of i in the given base,
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func FormatInt(i int64, base int) string {
if fastSmalls && 0 <= i && i < nSmalls && base == 10 {
return small(int(i))
}
_, s := formatBits(nil, uint64(i), base, i < 0, false)
return s
}
举个例子,我想把int32的666转换为字符串
package main
import (
"fmt"
"strconv"
)
func main() {
var num int32 = 666
fmt.Println("原始数字:", num)
str2 := strconv.FormatInt(int64(num), 2)
fmt.Println("二进制数字:", str2)
str10 := strconv.FormatInt(int64(num), 10)
fmt.Println("十进制数字:", str10)
}
//原始数字: 666
//二进制数字: 1010011010
//十进制数字: 666
//如果仅仅是整数到字符串,倒是还有一种方法
package main
import (
"fmt"
"strconv"
)
func main() {
num := 123
str := strconv.Itoa(num)
fmt.Println("String:", str) // Output: String: 123
}
//如果num的类型不是int,举个例子:int32
//那我们需要强制转成int才能传入方法。
对于浮点数就更麻烦一点,可以使用 strconv.FormatFloat() 函数将浮点数转换为字符串。这个函数允许我们指定格式、精度和位大小等参数。
让我们看看源码怎么说
// FormatFloat 将浮点数 f 转换为字符串,
// 根据格式fmt和精度prec
// 假设原始结果是从浮点获得的
// bitSize 位的值(float32 为 32,float64 为 64)。
//
// fmt 格式是其中之一
// 'b'(-ddddp±ddd,二进制指数),
// 'e' (-d.dddde±dd,十进制指数),
// 'E'(-d.ddddE±dd,十进制指数),
// 'f'(-ddd.dddd,无指数),
// 'g'('e'表示大指数,'f'否则),
// 'G'('E' 表示大指数,'f' 否则),
// 'x'(-0xd.ddddp±ddd,十六进制分数和二进制指数),或者
// 'X'(-0Xd.ddddP±ddd,十六进制分数和二进制指数)。
//
// 精度prec控制位数(不包括指数)
// 以 'e'、'E'、'f'、'g'、'G'、'x' 和 'X' 格式打印。
// 对于 'e'、'E'、'f'、'x' 和 'X',它是小数点后的位数。
// 对于“g”和“G”,它是有效数字的最大数量(尾随
// 零被删除)。
// 特殊精度-1使用最小位数
// 必要的,这样 ParseFloat 将准确返回 f。
func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize))
}
每次调用需要填写四个参数,来看看参数效果吧简单举几个例子
package main
import (
"fmt"
"strconv"
)
func main() {
// Example 1:
f1 := 3.14159
str1 := strconv.FormatFloat(f1, 'f', 2, 64)
fmt.Println("Example 1:", str1) // Output: 3.14
// Example 2: 科学计数法
f2 := 123456789.0
str2 := strconv.FormatFloat(f2, 'e', -1, 64)
fmt.Println("Example 2:", str2) // Output: 1.234568e+08
// Example 3: 去掉尾巴0
f3 := 42.0
str3 := strconv.FormatFloat(f3, 'f', -1, 64)
fmt.Println("Example 3:", str3) // Output: 42
// Example 4: 保留符号
f4 := -123.456
str4 := strconv.FormatFloat(f4, 'f', -1, 64)
fmt.Println("Example 4:", str4) // Output: -123.456
// Example 5: 指定精度
f5 := 2.7182818284590452353602874713527
str5 := strconv.FormatFloat(f5, 'f', 6, 64)
fmt.Println("Example 5:", str5) // Output: 2.718282
}
但是! Go语言贴心的准备了另外一套方法,fmt.Sprintf
package main
import (
"fmt"
)
func main() {
// Example 1: 整型转字符
num1 := 42
str1 := fmt.Sprintf("%d", num1)
fmt.Println("Example 1:", str1) // Output: 42
// Example 2: 浮点数保留小数点后两位
num2 := 3.14159
str2 := fmt.Sprintf("%.2f", num2)
fmt.Println("Example 2:", str2) // Output: 3.14
// Example 3: 科学计数法
num3 := 123456789.0
str3 := fmt.Sprintf("%.2e", num3)
fmt.Println("Example 3:", str3) // Output: 1.23e+08
// Example 4: 前端补零
num4 := 7
str4 := fmt.Sprintf("%05d", num4)
fmt.Println("Example 4:", str4) // Output: 00007
// Example 5: F指定精度
num5 := 2.7182818284590452353602874713527
str5 := fmt.Sprintf("%10.6f", num5)
fmt.Println("Example 5:", str5) // Output: 2.718282
}
总的来说,如果只是简单地将浮点数转换为字符串,并且性能要求不是非常苛刻,使用fmt.Sprintf会更加方便。但如果需要更精细的控制浮点数的格式,或者性能要求较高,那么strconv.FormatXxxx可能更适合。
在Java中,字符串到数字的转换通常涉及到使用Integer.parseInt()、Double.parseDouble()还有Integer.valueOf()、Long.valueOf() 等方法。这里需要注意的点是:parseXxxx() 等方法返回的是基本数据类型的值而valueOf() 方法返回的是对应包装类的对象。
//别忘了处理异常
String str = "123";
try {
int num = Integer.parseInt(str);
System.out.println("Integer value: " + num1); // Output: 123
} catch (NumberFormatException e) {
System.err.println(" NumberFormatException: " + e.getMessage());
}
与之前类似,字符转数字也令人头疼
####来看字符串到整数
//上面有Itoa,那这里就有Atoi, 不同于java的try-catch
//go语言的一些方法会直接返回两个值,第一个为我们需要的返回
//值,第二个为error。 一旦出现error,就会返回该类型的默认值
package main
import (
"fmt"
"strconv"
)
func main() {
str := "123"
num, err := strconv.Atoi(str)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Integer:", num) // Output: 123
}
同样,strconv.ParseInt 函数用于将字符串解析为整数。
// ParseInt interprets a string s in the given base (0, 2 to 36) and
// bit size (0 to 64) and returns the corresponding value i.
//
// The string may begin with a leading sign: "+" or "-".
//
// If the base argument is 0, the true base is implied by the string's
// prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o",
// 16 for "0x", and 10 otherwise. Also, for argument base 0 only,
// underscore characters are permitted as defined by the Go syntax for
// integer literals.
//
// The bitSize argument specifies the integer type
// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
// correspond to int, int8, int16, int32, and int64.
// If bitSize is below 0 or above 64, an error is returned.
//
// The errors that ParseInt returns have concrete type *NumError
// and include err.Num = s. If s is empty or contains invalid
// digits, err.Err = ErrSyntax and the returned value is 0;
// if the value corresponding to s cannot be represented by a
// signed integer of the given size, err.Err = ErrRange and the
// returned value is the maximum magnitude integer of the
// appropriate bitSize and sign.
func ParseInt(s string, base int, bitSize int) (i int64, err error) {
...
}
这一堆注释,看起来头痛,简单来说就是
s 是要解析的字符串。
base 是进制,通常是 2、8、10 或 16。如果 base 为 0,则会根据字符串的格式自动选择进制。
bitSize 是结果的位大小,通常是 0、8、16、32 或 64。
package main
import (
"fmt"
"strconv"
)
func parseIntExamples() {
// Example 1: Parse decimal string to int64
str1 := "12345"
num1, err := strconv.ParseInt(str1, 10, 64)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Integer 1:", num1) // Output: Integer 1: 12345
}
// Example 2: Parse binary string to int64
str2 := "1101"
num2, err := strconv.ParseInt(str2, 2, 64)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Integer 2:", num2) // Output: Integer 2: 13
}
// Example 3: Parse octal string to int64
str3 := "755"
num3, err := strconv.ParseInt(str3, 8, 64)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Integer 3:", num3) // Output: Integer 3: 493
}
// Example 4: Parse hexadecimal string to int64
str4 := "1A9"
num4, err := strconv.ParseInt(str4, 16, 64)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Integer 4:", num4) // Output: Integer 4: 425
}
}
func main() {
parseIntExamples()
}
再来看看浮点型,只需要两个参数,反而简单许多
// s 是要解析的字符串。
// bitSize 指定了结果的精度,可以是 32 或 64。
func ParseFloat(s string, bitSize int) (float64, error) {
//f 是要转换的浮点数。
//fmt 是格式标记,可以是 'f'(十进制格式)、'e'(科学计数法)、
//'E'(科学计数法,大写 'E')或 'g'(十进制或科学计数法)。
//prec 是精度,控制小数点后的位数。
//bitSize 是浮点数的位大小,可以是 32 或 64。
//例子如下
package main
import (
"fmt"
"strconv"
)
func parseFloatExamples() {
// Example 1: Parse regular decimal string to float64
str1 := "3.14"
num1, err := strconv.ParseFloat(str1, 64)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Float 1:", num1) // Output: Float 1: 3.14
}
// Example 2: Parse scientific notation to float64
str2 := "1.23e10"
num2, err := strconv.ParseFloat(str2, 64)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Float 2:", num2) // Output: Float 2: 1.23e+10
}
// Example 3: Parse invalid string to float64
str3 := "abc"
num3, err := strconv.ParseFloat(str3, 64)
if err != nil {
fmt.Println("Error:", err) // Output: Error: strconv.ParseFloat: parsing "abc": invalid syntax
} else {
fmt.Println("Float 3:", num3)
}
}
func main() {
parseFloatExamples()
}
在转换过程中,务必处理可能出现的错误。
根据需要选择合适的转换函数,并注意参数的意义和使用方式。
字符串的格式必须符合转换函数的要求,否则会导致转换失败。
使用 strconv 包中的函数可以完成各种类型的字符串转换,包括整数和浮点数,以及不同进制的转换。