Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Go math/rand 包详解

概述

math/rand 包实现了伪随机数生成器。该包提供了生成各种类型随机数的函数,包括整数、浮点数、随机排列等。适用于模拟、测试等非安全敏感场景。

重要说明

  • ⚠️ 不应用于安全敏感场景(如密码、令牌)
  • ✓ 适用于模拟、游戏、测试等场景
  • ✓ 包级别函数是线程安全的
  • Rand 类型不是线程安全的,需要加锁
  • ✓ Go 1.20+ 会自动种子化,无需手动调用 Seed

包导入

import "math/rand"

基本使用

1. 生成随机整数

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成随机整数
    fmt.Printf("随机 int: %d\n", rand.Int())
    fmt.Printf("随机 int64: %d\n", rand.Int63())
    fmt.Printf("随机 int31: %d\n", rand.Int31())
    
    // 生成范围内的随机数
    fmt.Printf("0-99: %d\n", rand.Intn(100))
    fmt.Printf("0-9: %d\n", rand.Int31n(10))
    fmt.Printf("0-999: %d\n", rand.Int63n(1000))
}

2. 生成随机浮点数

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成随机浮点数
    fmt.Printf("float64: %f\n", rand.Float64())
    fmt.Printf("float32: %f\n", rand.Float32())
}

3. 使用 Rand 对象

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 创建自定义随机源
    r := rand.New(rand.NewSource(42))
    
    // 使用 Rand 对象
    fmt.Printf("随机数 1: %d\n", r.Intn(100))
    fmt.Printf("随机数 2: %d\n", r.Intn(100))
    fmt.Printf("随机数 3: %d\n", r.Intn(100))
    
    // 重置种子,生成相同的序列
    r.Seed(42)
    fmt.Printf("重置后 1: %d\n", r.Intn(100))
}

一、包级别函数

ExpFloat64

定义:

func ExpFloat64() float64

说明:

  • 功能:返回指数分布的 float64
  • 返回值float64 - 范围 (0, +MaxFloat64]
  • 分布:速率参数 λ=1,均值=1
  • 用途:模拟事件间隔时间

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成指数分布随机数
    for i := 0; i < 5; i++ {
        fmt.Printf("%.4f\n", rand.ExpFloat64())
    }
    
    // 调整速率参数
    rate := 2.0
    sample := rand.ExpFloat64() / rate
    fmt.Printf("速率=%.2f 的样本:%.4f\n", rate, sample)
}

Float32

定义:

func Float32() float32

说明:

  • 功能:返回 [0.0, 1.0) 范围内的随机 float32
  • 返回值float32

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成 5 个随机 float32
    for i := 0; i < 5; i++ {
        fmt.Printf("%.4f\n", rand.Float32())
    }
}

Float64

定义:

func Float64() float64

说明:

  • 功能:返回 [0.0, 1.0) 范围内的随机 float64
  • 返回值float64

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成 5 个随机 float64
    for i := 0; i < 5; i++ {
        fmt.Printf("%.6f\n", rand.Float64())
    }
}

Int

定义:

func Int() int

说明:

  • 功能:返回非负随机整数
  • 返回值int - 范围 [0, MaxInt]

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成 5 个随机整数
    for i := 0; i < 5; i++ {
        fmt.Printf("%d\n", rand.Int())
    }
}

Int31

定义:

func Int31() int32

说明:

  • 功能:返回非负 31 位随机整数
  • 返回值int32 - 范围 [0, 2^31-1]

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    fmt.Printf("随机 int31: %d\n", rand.Int31())
    fmt.Printf("最大值:2^31-1 = %d\n", int32(^uint32(0)>>1))
}

Int31n

定义:

func Int31n(n int32) int32

说明:

  • 功能:返回 [0, n) 范围内的随机 int32
  • 参数n - 上界(必须 > 0)
  • 返回值int32
  • 注意:n <= 0 时会 panic

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 模拟骰子
    fmt.Printf("骰子:%d\n", rand.Int31n(6)+1)
    
    // 生成 10 个 0-99 的随机数
    for i := 0; i < 10; i++ {
        fmt.Printf("%d ", rand.Int31n(100))
    }
}

Int63

定义:

func Int63() int64

说明:

  • 功能:返回非负 63 位随机整数
  • 返回值int64 - 范围 [0, 2^63-1]

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    fmt.Printf("随机 int63: %d\n", rand.Int63())
}

Int63n

定义:

func Int63n(n int64) int64

说明:

  • 功能:返回 [0, n) 范围内的随机 int64
  • 参数n - 上界(必须 > 0)
  • 返回值int64
  • 注意:n <= 0 时会 panic

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 大范围随机数
    n := rand.Int63n(1000000)
    fmt.Printf("0-999999: %d\n", n)
}

Intn

定义:

func Intn(n int) int

说明:

  • 功能:返回 [0, n) 范围内的随机 int
  • 参数n - 上界(必须 > 0)
  • 返回值int
  • 注意:n <= 0 时会 panic

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 模拟骰子
    dice := rand.Intn(6) + 1
    fmt.Printf("骰子点数:%d\n", dice)
    
    // 随机数组索引
    items := []string{"苹果", "香蕉", "橙子", "葡萄"}
    randomItem := items[rand.Intn(len(items))]
    fmt.Printf("随机选择:%s\n", randomItem)
}

NormFloat64

定义:

func NormFloat64() float64

说明:

  • 功能:返回标准正态分布的 float64
  • 返回值float64 - 范围 [-MaxFloat64, +MaxFloat64]
  • 分布:均值=0,标准差=1
  • 用途:模拟自然现象、蒙特卡洛模拟

示例:

package main

import (
    "fmt"
    "math"
    "math/rand"
)

func main() {
    // 生成标准正态分布样本
    fmt.Println("标准正态分布 (μ=0, σ=1):")
    for i := 0; i < 5; i++ {
        fmt.Printf("%.4f\n", rand.NormFloat64())
    }
    
    // 调整均值和标准差
    mean := 100.0
    stddev := 15.0
    sample := rand.NormFloat64()*stddev + mean
    fmt.Printf("\n调整后 (μ=%.0f, σ=%.0f): %.4f\n", mean, stddev, sample)
    
    // 验证:生成 1000 个样本计算均值
    sum := 0.0
    for i := 0; i < 1000; i++ {
        sum += rand.NormFloat64()
    }
    fmt.Printf("1000 个样本的均值:%.4f (应接近 0)\n", sum/1000)
}

Perm

定义:

func Perm(n int) []int

说明:

  • 功能:返回 [0, n) 的随机排列
  • 参数n - 排列长度
  • 返回值[]int - 随机排列的切片

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成 0-9 的随机排列
    perm := rand.Perm(10)
    fmt.Printf("随机排列:%v\n", perm)
    
    // 洗牌算法
    cards := []string{"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}
    indices := rand.Perm(len(cards))
    
    fmt.Print("洗牌后:")
    for _, idx := range indices {
        fmt.Printf("%s ", cards[idx])
    }
}

Read

定义:

func Read(p []byte) (n int, err error)

说明:

  • 功能:生成随机字节填充到 p
  • 参数p - 字节切片
  • 返回值
    • n - 读取的字节数(总是 len(p))
    • err - 错误(总是 nil)
  • 注意:已废弃,建议使用 crypto/rand.Read

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 生成随机字节
    data := make([]byte, 16)
    n, _ := rand.Read(data)
    
    fmt.Printf("读取 %d 字节:%x\n", n, data)
    fmt.Printf("十六进制:%X\n", data)
}

Seed

定义:

func Seed(seed int64)

说明:

  • 功能:设置随机数生成器的种子
  • 参数seed - 种子值
  • 注意
    • Go 1.20+ 会自动种子化
    • 相同种子产生相同的随机序列

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 设置种子
    rand.Seed(42)
    
    // 生成随机序列
    fmt.Print("序列 1: ")
    for i := 0; i < 5; i++ {
        fmt.Printf("%d ", rand.Intn(100))
    }
    
    // 重置相同种子
    rand.Seed(42)
    fmt.Print("\n序列 2: ")
    for i := 0; i < 5; i++ {
        fmt.Printf("%d ", rand.Intn(100))
    }
    fmt.Println("\n两个序列相同!")
}

Shuffle

定义:

func Shuffle(n int, swap func(i, j int))

说明:

  • 功能:随机打乱序列
  • 参数
    • n - 序列长度
    • swap - 交换函数

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 打乱切片
    numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    fmt.Printf("打乱前:%v\n", numbers)
    
    rand.Shuffle(len(numbers), func(i, j int) {
        numbers[i], numbers[j] = numbers[j], numbers[i]
    })
    
    fmt.Printf("打乱后:%v\n", numbers)
}

Uint32

定义:

func Uint32() uint32

说明:

  • 功能:返回随机 32 位无符号整数
  • 返回值uint32 - 范围 [0, 2^32-1]

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    fmt.Printf("随机 uint32: %d\n", rand.Uint32())
    fmt.Printf("十六进制:0x%08X\n", rand.Uint32())
}

二、Rand 类型

Rand 结构体

定义:

type Rand struct {
    // 包含未导出的字段
}

说明:

  • 功能:随机数生成器
  • 特点
    • 不是线程安全的
    • 可自定义 Source
    • 可重现随机序列

New

定义:

func New(src Source) *Rand

说明:

  • 功能:创建新的 Rand 实例
  • 参数src - 随机源
  • 返回值*Rand

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 创建自定义随机源
    source := rand.NewSource(12345)
    r := rand.New(source)
    
    // 使用自定义随机源
    fmt.Printf("Intn(100): %d\n", r.Intn(100))
    fmt.Printf("Float64: %f\n", r.Float64())
    fmt.Printf("Perm(5): %v\n", r.Perm(5))
}

NewSource

定义:

func NewSource(seed int64) Source

说明:

  • 功能:创建新的随机源
  • 参数seed - 种子值
  • 返回值Source

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 创建多个独立的随机源
    src1 := rand.NewSource(100)
    src2 := rand.NewSource(200)
    
    r1 := rand.New(src1)
    r2 := rand.New(src2)
    
    fmt.Printf("r1: %d, %d, %d\n", r1.Intn(1000), r1.Intn(1000), r1.Intn(1000))
    fmt.Printf("r2: %d, %d, %d\n", r2.Intn(1000), r2.Intn(1000), r2.Intn(1000))
}

Rand 方法

ExpFloat64

定义:

func (r *Rand) ExpFloat64() float64

说明:

  • 功能:返回指数分布的 float64
  • 同包级别函数

Float32

定义:

func (r *Rand) Float32() float32

说明:

  • 功能:返回 [0.0, 1.0) 范围内的随机 float32

Float64

定义:

func (r *Rand) Float64() float64

说明:

  • 功能:返回 [0.0, 1.0) 范围内的随机 float64

Int

定义:

func (r *Rand) Int() int

说明:

  • 功能:返回非负随机整数

Int31

定义:

func (r *Rand) Int31() int32

说明:

  • 功能:返回非负 31 位随机整数

Int31n

定义:

func (r *Rand) Int31n(n int32) int32

说明:

  • 功能:返回 [0, n) 范围内的随机 int32

Int63

定义:

func (r *Rand) Int63() int64

说明:

  • 功能:返回非负 63 位随机整数

Int63n

定义:

func (r *Rand) Int63n(n int64) int64

说明:

  • 功能:返回 [0, n) 范围内的随机 int64

Intn

定义:

func (r *Rand) Intn(n int) int

说明:

  • 功能:返回 [0, n) 范围内的随机 int

NormFloat64

定义:

func (r *Rand) NormFloat64() float64

说明:

  • 功能:返回标准正态分布的 float64

Perm

定义:

func (r *Rand) Perm(n int) []int

说明:

  • 功能:返回 [0, n) 的随机排列

Read

定义:

func (r *Rand) Read(p []byte) (n int, err error)

说明:

  • 功能:生成随机字节

Seed

定义:

func (r *Rand) Seed(seed int64)

说明:

  • 功能:设置种子

Shuffle

定义:

func (r *Rand) Shuffle(n int, swap func(i, j int))

说明:

  • 功能:随机打乱序列

示例:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    r := rand.New(rand.NewSource(42))
    
    cards := []string{"A", "K", "Q", "J", "10"}
    fmt.Printf("打乱前:%v\n", cards)
    
    r.Shuffle(len(cards), func(i, j int) {
        cards[i], cards[j] = cards[j], cards[i]
    })
    
    fmt.Printf("打乱后:%v\n", cards)
}

Uint32

定义:

func (r *Rand) Uint32() uint32

说明:

  • 功能:返回随机 32 位无符号整数

三、Source 类型

Source 接口

定义:

type Source interface {
    Int63() int64
    Seed(seed int64)
}

说明:

  • 功能:随机源接口
  • 用途:实现自定义随机数生成器

四、典型示例

示例 1:生成随机密码

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func generatePassword(length int) string {
    const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
    
    // Go 1.20+ 不需要手动 Seed
    // rand.Seed(time.Now().UnixNano())
    
    password := make([]byte, length)
    for i := 0; i < length; i++ {
        password[i] = charset[rand.Intn(len(charset))]
    }
    
    return string(password)
}

func main() {
    fmt.Println("随机密码生成:")
    for i := 0; i < 5; i++ {
        fmt.Printf("%d: %s\n", i+1, generatePassword(12))
    }
}

示例 2:随机抽样

package main

import (
    "fmt"
    "math/rand"
)

// 从总体中随机抽取 k 个样本(不放回)
func sample(population []string, k int) []string {
    if k > len(population) {
        k = len(population)
    }
    
    // 复制总体
    pool := make([]string, len(population))
    copy(pool, population)
    
    // Fisher-Yates 洗牌
    for i := 0; i < k; i++ {
        j := i + rand.Intn(len(pool)-i)
        pool[i], pool[j] = pool[j], pool[i]
    }
    
    return pool[:k]
}

func main() {
    population := []string{"Alice", "Bob", "Charlie", "David", "Eve", 
                          "Frank", "Grace", "Henry", "Ivy", "Jack"}
    
    fmt.Println("从 10 人中随机抽取 3 人:")
    for i := 0; i < 3; i++ {
        fmt.Printf("第 %d 次:%v\n", i+1, sample(population, 3))
    }
}

示例 3:蒙特卡洛模拟(计算π)

package main

import (
    "fmt"
    "math/rand"
)

func estimatePi(samples int) float64 {
    inside := 0
    
    for i := 0; i < samples; i++ {
        x := rand.Float64()
        y := rand.Float64()
        
        // 检查点是否在单位圆内
        if x*x + y*y <= 1 {
            inside++
        }
    }
    
    // π/4 ≈ inside/samples
    return 4.0 * float64(inside) / float64(samples)
}

func main() {
    fmt.Println("蒙特卡洛方法估算π:")
    
    samples := []int{1000, 10000, 100000, 1000000}
    for _, n := range samples {
        pi := estimatePi(n)
        fmt.Printf("样本数 %7d: π ≈ %.6f\n", n, pi)
    }
}

示例 4:随机漫步模拟

package main

import (
    "fmt"
    "math/rand"
)

func randomWalk(steps int) []int {
    position := 0
    path := []int{0}
    
    for i := 0; i < steps; i++ {
        if rand.Intn(2) == 0 {
            position++
        } else {
            position--
        }
        path = append(path, position)
    }
    
    return path
}

func main() {
    fmt.Println("随机漫步模拟:")
    path := randomWalk(20)
    
    for i, pos := range path {
        fmt.Printf("步骤 %2d: %3d ", i, pos)
        // 可视化
        if pos >= 0 {
            fmt.Print("→ ")
            for j := 0; j < pos; j++ {
                fmt.Print("  ")
            }
            fmt.Println("●")
        } else {
            fmt.Print("← ")
            for j := 0; j < -pos; j++ {
                fmt.Print("  ")
            }
            fmt.Println("●")
        }
    }
    fmt.Printf("\n最终位置:%d\n", path[len(path)-1])
}

示例 5:模拟掷骰子

package main

import (
    "fmt"
    "math/rand"
)

func rollDice(sides int) int {
    return rand.Intn(sides) + 1
}

func rollMultipleDice(count, sides int) []int {
    results := make([]int, count)
    for i := 0; i < count; i++ {
        results[i] = rollDice(sides)
    }
    return results
}

func main() {
    fmt.Println("掷骰子模拟:")
    
    // 掷 10 次 6 面骰
    fmt.Println("\n10 次 d6:")
    for i := 0; i < 10; i++ {
        fmt.Printf("%d ", rollDice(6))
    }
    
    // 掷 5 次 20 面骰
    fmt.Println("\n\n5 次 d20:")
    for i := 0; i < 5; i++ {
        fmt.Printf("%d ", rollDice(20))
    }
    
    // 3 个 6 面骰
    fmt.Println("\n\n3d6 (5 次):")
    for i := 0; i < 5; i++ {
        rolls := rollMultipleDice(3, 6)
        sum := 0
        for _, r := range rolls {
            sum += r
        }
        fmt.Printf("%v = %d\n", rolls, sum)
    }
}

示例 6:随机字符串生成

package main

import (
    "fmt"
    "math/rand"
)

const (
    letters       = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    digits        = "0123456789"
    specialChars  = "!@#$%^&*()_+-=[]{}|;:,.<>?"
)

func randomString(length int, charset string) string {
    b := make([]byte, length)
    for i := range b {
        b[i] = charset[rand.Intn(len(charset))]
    }
    return string(b)
}

func main() {
    fmt.Println("随机字符串生成:")
    
    // 纯字母
    fmt.Printf("字母 (10): %s\n", randomString(10, letters))
    
    // 字母 + 数字
    fmt.Printf("字母数字 (10): %s\n", randomString(10, letters+digits))
    
    // 所有字符
    fmt.Printf("所有字符 (10): %s\n", randomString(10, letters+digits+specialChars))
}

示例 7:抽奖系统

package main

import (
    "fmt"
    "math/rand"
)

type Lottery struct {
    participants []string
    winners      []string
}

func NewLottery() *Lottery {
    return &Lottery{
        participants: make([]string, 0),
        winners:      make([]string, 0),
    }
}

func (l *Lottery) AddParticipant(name string) {
    l.participants = append(l.participants, name)
}

func (l *Lottery) DrawWinners(count int) []string {
    if count > len(l.participants) {
        count = len(l.participants)
    }
    
    // 复制参与者列表
    pool := make([]string, len(l.participants))
    copy(pool, l.participants)
    
    // 抽取获奖者
    winners := make([]string, 0, count)
    for i := 0; i < count; i++ {
        idx := rand.Intn(len(pool))
        winners = append(winners, pool[idx])
        // 移除已中奖者
        pool[idx] = pool[len(pool)-1]
        pool = pool[:len(pool)-1]
    }
    
    l.winners = append(l.winners, winners...)
    return winners
}

func main() {
    lottery := NewLottery()
    
    // 添加参与者
    participants := []string{"张三", "李四", "王五", "赵六", "钱七", 
                           "孙八", "周九", "吴十", "郑十一", "王十二"}
    for _, p := range participants {
        lottery.AddParticipant(p)
    }
    
    fmt.Println("抽奖系统")
    fmt.Printf("参与者:%d 人\n", len(participants))
    
    // 抽取 3 名获奖者
    fmt.Println("\n开始抽奖...")
    winners := lottery.DrawWinners(3)
    
    fmt.Println("\n获奖者名单:")
    for i, w := range winners {
        fmt.Printf("%d. %s\n", i+1, w)
    }
}

示例 8:并发安全的随机数生成

package main

import (
    "fmt"
    "math/rand"
    "sync"
)

// 线程安全的随机数生成器
type SafeRand struct {
    mu sync.Mutex
    r  *rand.Rand
}

func NewSafeRand(seed int64) *SafeRand {
    return &SafeRand{
        r: rand.New(rand.NewSource(seed)),
    }
}

func (sr *SafeRand) Intn(n int) int {
    sr.mu.Lock()
    defer sr.mu.Unlock()
    return sr.r.Intn(n)
}

func (sr *SafeRand) Float64() float64 {
    sr.mu.Lock()
    defer sr.mu.Unlock()
    return sr.r.Float64()
}

func main() {
    safeRand := NewSafeRand(42)
    
    var wg sync.WaitGroup
    results := make([]int, 10)
    
    // 并发生成随机数
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(idx int) {
            defer wg.Done()
            results[idx] = safeRand.Intn(100)
        }(i)
    }
    
    wg.Wait()
    
    fmt.Println("并发安全的随机数:")
    fmt.Println(results)
}

五、最佳实践

1. 使用包级别函数(简单场景)

// ✓ 好的做法:简单场景使用包级别函数
n := rand.Intn(100)
f := rand.Float64()

// 包级别函数是线程安全的

2. 使用 Rand 对象(需要控制种子)

// ✓ 好的做法:需要重现性时使用 Rand
r := rand.New(rand.NewSource(42))
n1 := r.Intn(100)

r.Seed(42)
n2 := r.Intn(100) // n1 == n2

3. Go 1.20+ 不需要手动 Seed

// Go 1.20+ 会自动种子化
// 不需要:rand.Seed(time.Now().UnixNano())

// ✓ 直接使用
n := rand.Intn(100)

4. 并发场景使用锁

// ✓ 好的做法:并发时使用锁
type SafeRand struct {
    mu sync.Mutex
    r  *rand.Rand
}

5. 安全敏感场景使用 crypto/rand

// ✗ 错误:不应用于安全场景
password := rand.Intn(1000000) // 不安全!

// ✓ 好的做法:使用 crypto/rand
import "crypto/rand"

六、与其他包配合

1. 与 time 包配合(Go 1.19 及以下)

import (
    "math/rand"
    "time"
)

// Go 1.19 及以下需要手动种子化
rand.Seed(time.Now().UnixNano())

2. 与 crypto/rand 配合

import (
    "crypto/rand"
    "math/big"
)

// 生成加密安全的随机数
n, _ := rand.Int(rand.Reader, big.NewInt(100))

3. 与 slices 包配合

import (
    "math/rand"
    "slices"
)

// 打乱切片
slices.Shuffle(data, func(i, j int) {
    data[i], data[j] = data[j], data[i]
})

七、快速参考

包级别函数

函数参数返回值功能
ExpFloat64float64指数分布
Float32float32[0,1) 随机 float32
Float64float64[0,1) 随机 float64
Intint随机非负 int
Int31int32随机 31 位 int
Int31nn int32int32[0,n) 随机 int32
Int63int64随机 63 位 int
Int63nn int64int64[0,n) 随机 int64
Intnn intint[0,n) 随机 int
NormFloat64float64标准正态分布
Permn int[]int[0,n) 随机排列
Readp []byte(int, error)随机字节
Seedseed int64设置种子
Shufflen int, swap打乱序列
Uint32uint32随机 uint32

Rand 方法

Rand 类型的方法与包级别函数基本相同,只是需要通过 Rand 实例调用。


八、注意事项

1. 不适用于安全场景

// ✗ 不安全的做法
token := rand.Int63() // 可预测!

// ✓ 安全的做法
import "crypto/rand"
n, _ := rand.Int(rand.Reader, big.NewInt(1000000))

2. 并发安全

// 包级别函数是线程安全的
// Rand 对象不是线程安全的,需要加锁

3. 种子重复

// 相同种子产生相同序列
rand.Seed(42)
fmt.Println(rand.Intn(100)) // 总是相同

// Go 1.20+ 自动种子化,避免此问题

4. 范围验证

// n <= 0 会 panic
rand.Intn(0)   // panic!
rand.Intn(-1)  // panic!

// ✓ 好的做法
if n > 0 {
    rand.Intn(n)
}

最后更新: 2026-04-05
Go 版本: Go 1.20+
包文档: https://pkg.go.dev/math/rand