Go源码--Strconv库

简介

Strconv 库是一些跨类型的转换函数集合,大家应该很熟悉。源码没有什么难点,主要是面试题有可能会出这种类型的,所以简单介绍下,主要介绍 以下两种常用转换,其他的没细研究,感兴趣的可以看看。

Strconv.Atoi 函数

将 字符串数组 转换为 数字,比较简单,源码如下

// Atoi  算法 核心思想 就是 每个字符 跟 ’0‘ 求差 然后迭代相加。因为面试可能会出这种题,可以借鉴下 整体不太难
func Atoi(s string) (int, error) {
	const fnAtoi = "Atoi"

	sLen := len(s)
	if intSize == 32 && (0 < sLen && sLen < 10) ||  // intSize = 32 << (^uint(0) >> 63) 操作系统位数 ;如果是 32为操作系统,为 32<<0 32左移0位 还是 32,如果是64位 则 ^uint(0) >> 63==1 32左移1位就是64
		intSize == 64 && (0 < sLen && sLen < 19) {
		// Fast path for small integers that fit int type.
		s0 := s   // 这边之所以会复制一份 就是为了 将 对 s的处理 跟 输出 完整s信息和使用完整s进行一些判断 分开,使得逻辑简单。
		if s[0] == '-' || s[0] == '+' {  // 处理符号
			s = s[1:]
			if len(s) < 1 {
				return 0, syntaxError(fnAtoi, s0)
			}
		}

		n := 0
		for _, ch := range []byte(s) {  // 面试常考
			ch -= '0'
			if ch > 9 {
				return 0, syntaxError(fnAtoi, s0)
			}
			n = n*10 + int(ch)  // n 是每次迭代的结果
		}
		if s0[0] == '-' {
			n = -n
		}
		return n, nil // 返回
	}

	// Slow path for invalid, big, or underscored integers.
	i64, err := ParseInt(s, 10, 0)  // 大数或者 无效整数走这里,感兴趣的可以看看
	if nerr, ok := err.(*NumError); ok {
		nerr.Func = fnAtoi
	}
	return int(i64), err
}

Strconv.Itoa 函数

Itoa 将 数字转换为字符串 其调用链如下
](https://img-blog.csdnimg.cn/direct/66f9267ce02a4d56923a3a3108c2c0e3.png)

我们来看 formatBits 源码


// formatBits 执行逻辑:(只讲解10进制) 就是 将大数 %100 然后 再采取 在 smallsString映射的方法 查找 对应字符 再迭代。面试常考
func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s string) { // base 进制 如果是 10 就对应  Itoa(i)
	if base < 2 || base > len(digits) {
		panic("strconv: illegal AppendInt/FormatInt base")
	}
	// 2 <= base && base <= len(digits)

	var a [64 + 1]byte // +1 for sign of 64bit value in base 2 // 结果字节数组
	i := len(a)        // 长度 初始 为 65

	if neg {
		u = -u
	}

	// convert bits
	// We use uint values where we can because those will
	// fit into a single register even on a 32bit machine.
	if base == 10 {
		// common case: use constants for / because
		// the compiler can optimize it into a multiply+shift

		if host32bit { // 32位 操作系统 感兴趣的可以自己看看
		// ... 
		}

		// u guaranteed to fit into a uint
		us := uint(u) // 转换成平台自适应 类型
		for us >= 100 { 
			is := us % 100 * 2 // is 是 在 smallString 提取的起始索引
			us /= 100          // us是下次扫描数据
			i -= 2             // 一次可以获取两个
			a[i+1] = smallsString[is+1]
			a[i+0] = smallsString[is+0]
		}

		// us < 100
		is := us * 2              // 走到这里 小于 100了
		i--                       // 更新 值
		a[i] = smallsString[is+1] // 输出结果
		if us >= 10 {             // 小于10 就只有上面结果 大于10 则还需要输出 smallsString[is]
			i--
			a[i] = smallsString[is]
		}

	} else if isPowerOfTwo(base) { // 是 二进制 走这里
	// ... 
	}

	// add sign, if any
	if neg { // 如果是负值 则 在前面加 -
		i--
		a[i] = '-'
	}

	if append_ { // true 返回 byte数组
		d = append(dst, a[i:]...)
		return
	}
	s = string(a[i:]) // 返回字符串
	return
}
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值