go语言 strconv.ParseInt 的实现分析
字符串与数值之间进行转换是一个高频操作,在go语言中,SDK提供 strconv.ParseInt
将字符串转换为数值,strconv.FormatInt
可以将数值转换为字符串。
1.首先看下 strconv.ParseInt
函数如何使用:
func ParseInt(s string, base int, bitSize int) (i int64, err error){}
参数:
- s:数字的字符串形式
- base:数字字符串的进制,比如:2进制、10进制。
- bitSize:预期数值的bit大小,用于数值上限限制,最终返回的还是int64类型
2.下面看下函数的具体实现:
strconv.ParseInt
是 strconv.ParseUint
的一个包装层,区别在数值结果的基础上处理符号,因此具体的实现在strconv.ParseUint
里面。
func ParseUint(s string, base int, bitSize int) (uint64, error) {
...
case base == 0:
// Look for octal, hex prefix.
base = 10 // 当base = 0,默认 base 按赋值10进制
if s[0] == '0' {
switch {
case len(s) >= 3 && lower(s[1]) == 'b': // 根据字符串的前缀,来判断二进制。下面同理
base = 2
s = s[2:]
case len(s) >= 3 && lower(s[1]) == 'o':
base = 8
s = s[2:]
case len(s) >= 3 && lower(s[1]) == 'x':
base = 16
s = s[2:]
default:
base = 8 // 当 0 开头,默认8进制
s = s[1:]
}
}
default:
return 0, baseError(fnParseUint, s0, base)
}
}
根据进制 base 进制数计算数值,支持2~ 36进制[0-9A-Z]
func ParseUint(s string, base int, bitSize int) (uint64, error) {
...
// 逐个字符判断,然后累加求和
for _, c := range []byte(s) {
var d byte
switch {
case c == '_' && base0:
underscores = true
continue
case '0' <= c && c <= '9':
d = c - '0'
// 支持2 ~ 36进制
case 'a' <= lower(c) && lower(c) <= 'z':
d = lower(c) - 'a' + 10
default:
return 0, syntaxError(fnParseUint, s0)
}
if d >= byte(base) {
return 0, syntaxError(fnParseUint, s0)
}
if n >= cutoff {
// n*base overflows
return maxVal, rangeError(fnParseUint, s0)
}
n *= uint64(base)
n1 := n + uint64(d)
if n1 < n || n1 > maxVal {
// n+v overflows
return maxVal, rangeError(fnParseUint, s0)
}
n = n1
}
}
3.使用strconv.FormatInt
将数值转换为字符串
func FormatInt(i int64, base int) string {}
参数:
- i:10进制数值
- base:进制数
示例:
// 将10进制数 15 转换为 16 进制的字符串形式
func Test_FormatUint(t *testing.T) {
val := strconv.FormatUint(15, 16)
fmt.Println(val) // output:f
}