如何通过位运算将任意负值转为0,替代Go链表操作中的if判断?
实现方案
你要的无分支位运算实现可以通过有符号整数的算术右移特性完成,核心利用负数最高符号位为1的特点,当递减后的值为负时自动清零,修改后代码如下:
import "strconv" // PopBack will remove an item from the end of the linked list func (ll *LinkedList) PopBack() { lastNode := &ll.node for *lastNode != nil && (*lastNode).next != nil { lastNode = &(*lastNode).next } *lastNode = nil // 位运算等价于 ll.size = max(ll.size - 1, 0) ll.size -= 1 ll.size &= ^(ll.size >> (strconv.IntSize - 1)) }
原理解释
- Go中对有符号整数执行右移操作为算术右移,会自动补充符号位:
- 当
ll.size - 1 >= 0时,右移strconv.IntSize - 1位的结果为0,取反后是二进制全1,和原值做与运算后值保持不变 - 当
ll.size - 1 < 0时,右移strconv.IntSize - 1位的结果为-1(二进制全1),取反后是二进制全0,和原值做与运算后结果直接清零
- 当
- 如果你的
size字段固定为int32/int64类型,可以直接将位移量替换为31/63,无需导入strconv包 - 注意:该方案仅适用于
size为有符号整数的场景,无符号整数不支持该逻辑
额外说明
该写法虽然去掉了if分支,但可读性远不如原生的条件判断,而且现代Go编译器对这类简单边界分支的优化已经非常成熟,实际运行性能几乎没有差异,非极端性能敏感场景更推荐保留原有的if写法,可维护性更高。
内容的提问来源于stack exchange,提问作者Aziz
相关产品推荐
相关产品推荐

