likes
comments
collection
share

Java 与 Go:数字和字符串的相互转换

作者站长头像
站长
· 阅读数 5

今天我们继续来学习Java和Go语言在数字和字符串转换方面的不同的特性和用法。本文将比较Java语言和Go语言在数字和字符串转换方面的异同,以帮助大家更好地理解它们。

数字转字符串

Java:

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:

但是到了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:

在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());
        }

Go:

与之前类似,字符转数字也令人头疼

####来看字符串到整数

//上面有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 包中的函数可以完成各种类型的字符串转换,包括整数和浮点数,以及不同进制的转换。

One more thing

需要Copilot、JetBrains 全家桶全插件全主题

详情可以咨询客服

关注AIGoland之星,添加“星标”

获取每天技术干货,突破自我,成为牛逼架构师

IT一线从业者抱团群

致力于帮助广大开发者提供高效合适的工具,让大家能够腾出手做更多创造性的工作,也欢迎大家分享自己公司的内推信息,相互帮助,一起进步!

组建了程序员,架构师,IT从业者交流群,以交流技术、职位内推、行业探讨为主

图片

想要体验jetbrain全家桶的小伙伴快来关注公众号,回复idea,更多更好玩的东西稍后就来