Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修复了:32位编译时整数溢出错误,同时满足项目go1.13版本要求。
满足go1.13版本的修改方案:int(^uint(0) >> 1)
大于go1.17版本的修改方案:math.MaxInt(go1.17版本开始支持math.MaxInt)
修复这个PR(https://github.com/larksuite/oapi-sdk-go/pull/192)不满足go1.13版本的问题
根本原因: 在 service/drive/v1/api_ext.go:30 使用了 math.MaxInt64,而在32位系统上 int 类型是32位的,最大值只有 2147483647,无法容纳 math.MaxInt64 的值 9223372036854775807,导致编译时整数溢出错误。
解决方案: 使用位运算 int(^uint(0) >> 1) 动态获取当前平台的最大int值,兼容所有架构。
详细解释一下 int(^uint(0) >> 1) 和 math.MaxInt64 的区别:
math.MaxInt64 vs int(^uint(0) >> 1)
const MaxInt64 = 1<<63 - 1 // = 9223372036854775807
type ListFileIterator struct {
limit int // 32位系统: int = int32, 范围 -2^31 到 2^31-1
}
// 32位系统编译错误:
limit: math.MaxInt64 // ❌ 9223372036854775807 超过 int32 的最大值 2147483647
这是一个位运算技巧,逐步分解:
步骤1: uint(0)
32位系统: 00000000 00000000 00000000 00000000 (uint32)
64位系统: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 (uint64)
步骤2: ^uint(0) (按位取反)
32位系统: 11111111 11111111 11111111 11111111 = 4294967295 (2^32-1)
64位系统: 11111111...11111111 (64个1) = 18446744073709551615 (2^64-1)
步骤3: ^uint(0) >> 1 (右移1位)
32位系统: 01111111 11111111 11111111 11111111 = 2147483647 (2^31-1) = MaxInt32
64位系统: 01111111...11111111 (1个0 + 63个1) = 9223372036854775807 (2^63-1) = MaxInt64
步骤4: int(...) (转换为int)
32位系统: int(2147483647) = 2147483647 ✅
64位系统: int(9223372036854775807) = 9223372036854775807 ✅
┌──────────────┬─────────────────────┬────────────────────────────────┐
│ 特性 │ math.MaxInt64 │ int(^uint(0) >> 1) │
├──────────────┼─────────────────────┼────────────────────────────────┤
│ 值(32位系统) │ 9223372036854775807 │ 2147483647 (MaxInt32) │
├──────────────┼─────────────────────┼────────────────────────────────┤
│ 值(64位系统) │ 9223372036854775807 │ 9223372036854775807 (MaxInt64) │
├──────────────┼─────────────────────┼────────────────────────────────┤
│ 32位编译 │ ❌ 溢出错误 │ ✅ 成功 │
├──────────────┼─────────────────────┼────────────────────────────────┤
│ 64位编译 │ ✅ 成功 │ ✅ 成功 │
├──────────────┼─────────────────────┼────────────────────────────────┤
│ 适配性 │ 固定64位 │ 自动适配平台 │
└──────────────┴─────────────────────┴────────────────────────────────┘
package main
import (
"fmt"
"math"
"unsafe"
)
func main() {
intSize := unsafe.Sizeof(int(0)) * 8
fmt.Printf("当前系统 int 大小: %d 位\n", intSize)
}
Go 语言的 int 类型大小是平台相关的:
当你需要一个"尽可能大的int值"时:
从 Go 1.17 开始,标准库提供了更清晰的方式:
import "math"
const maxInt = math.MaxInt // 自动适配平台
但飞书SDK使用的是 go 1.13,所以需要手动实现这个技巧。
总结