52 / 68

math/rand

math/rand paketi

math/rand — tasodifiy sonlar yaratish uchun ishlatiladigan standart paket. O'yinlar, simulyatsiyalar, test ma'lumotlarini yaratish yoki elementlarni tasodifiy tartibda aralashtirish kabi vazifalarda keng qo'llaniladi.

example.go
import "math/rand"

[!IMPORTANT] math/rand kriptografik jihatdan xavfsiz emas — ya'ni parollar, tokenlar yoki maxfiy kalitlar yaratish uchun ishlatilmasligi kerak! Bunday maqsadlar uchun crypto/rand paketidan foydalaning.


1. Tasodifiy butun son: Intn()

rand.Intn(n) 0 dan n-1 gacha (n dan tashqari) oraliqda tasodifiy butun son qaytaradi:

example.go
package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 0 dan 99 gacha (100 dan tashqari) tasodifiy son
    num := rand.Intn(100)

    fmt.Println(num)
}

Natija (har safar boshqacha bo'lishi mumkin):

kod
73

[!NOTE] Go 1.20 versiyasidan boshlab, math/rand dasturni ishga tushirgan har safar avtomatik ravishda turlicha "urug'" (seed) bilan boshlanadi. Shuning uchun eski Go kodlarida ko'p uchraydigan rand.Seed(time.Now().UnixNano()) qatorini yozish endi shart emas.

Ma'lum bir diapazonda (masalan, 10 dan 20 gacha) tasodifiy son kerak bo'lsa:

example.go
min, max := 10, 20
num := min + rand.Intn(max-min+1) // 10 dan 20 gacha (ikkalasi ham kiradi)

2. Tasodifiy kasr son: Float64()

0.0 (kiritiladi) dan 1.0 gacha (kiritilmaydi) oraliqdagi tasodifiy kasr son:

example.go
package main

import (
    "fmt"
    "math/rand"
)

func main() {
    fmt.Println(rand.Float64())
}

Natija (har safar boshqacha):

kod
0.6273588491262540

3. Slaysni tasodifiy aralashtirish: Shuffle()

Kartalar, viktorina savollari yoki har qanday ro'yxatni tasodifiy tartibga solish uchun rand.Shuffle() ishlatiladi:

example.go
package main

import (
    "fmt"
    "math/rand"
)

func main() {
    nums := []int{1, 2, 3, 4, 5}

    // len(nums) — nechta element borligi
    // funksiya ichida i va j pozitsiyalarni almashtirish mantig'i yoziladi
    rand.Shuffle(len(nums), func(i, j int) {
        nums[i], nums[j] = nums[j], nums[i]
    })

    fmt.Println(nums)
}

Natija (tartib har safar boshqacha bo'ladi):

kod
[3 1 5 2 4]

4. Takrorlanadigan (deterministik) tasodifiy sonlar: rand.New() va NewSource()

Ba'zan (masalan, testlarda) "tasodifiy", lekin har safar bir xil natija beradigan sonlar kerak bo'ladi. Buning uchun o'z generatorimizni aniq "urug'" (seed) bilan yaratamiz:

example.go
package main

import (
    "fmt"
    "math/rand"
)

func main() {
    // 42 — urug' (seed): shu son bir xil bo'lsa, natijalar ketma-ketligi ham bir xil bo'ladi
    r := rand.New(rand.NewSource(42))

    fmt.Println(r.Intn(50))
    fmt.Println(r.Intn(50))
}

Natija (dasturni necha marta ishga tushirmang, natija doim shunday bo'ladi):

kod
37
5

Bu xususiyat, ayniqsa, avtomatlashtirilgan testlarda "tasodifiy" ma'lumot bilan ishlashni takrorlanadigan qilish uchun juda foydali.


5. Yangi avlod: math/rand/v2

Go 1.22 versiyasidan boshlab, standart kutubxonaga yangilangan math/rand/v2 paketi qo'shildi — u tezroq ishlaydi va funksiya nomlari biroz o'zgargan (masalan, Intn o'rniga IntN, katta harf bilan):

example.go
package main

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

func main() {
    fmt.Println(rand.IntN(100)) // e'tibor bering: Intn emas, IntN
    fmt.Println(rand.Float64())
}

[!NOTE] Yangi loyihalarda imkon qadar math/rand/v2 dan foydalanish tavsiya etiladi, lekin math/rand ham hali to'liq qo'llab-quvvatlanadi va ko'plab mavjud loyihalarda uchraydi — shuning uchun ikkalasini ham tanish muhim.


Xulosa: qachon qaysi funksiya kerak?

VazifaFunksiya
0 dan n-1 gacha tasodifiy sonrand.Intn(n)
0.0 dan 1.0 gacha tasodifiy kasr sonrand.Float64()
Slaysni tasodifiy aralashtirishrand.Shuffle()
Har safar bir xil ("takrorlanadigan") tasodifiy natijarand.New(rand.NewSource(urug'))
Maxfiy/xavfsizlik uchun tasodifiy qiymatmath/rand → crypto/rand