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.ParseIntstrconv.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
}
posted @ 2020-11-28 14:18  MarsZuo  阅读(2540)  评论(0编辑  收藏  举报