rand

package module
v0.0.0-...-7c2acee Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 8, 2019 License: Apache-2.0 Imports: 2 Imported by: 7

README

Rand

The built-in math/rand library is not very condusive to injection or testability:

  1. The way the rand.Rand library computes its values differs widely per type (e.g. an Int vs Int31 grabs different halves of the rand.Source's 64-bit field). This makes test fakes very impractical.
  2. Use of the global rand methods prohibit test injection, but the struct interface isn't goroutine safe.

To fix these, this rand ipmlementation can fully supplant math/rand. The library performs three primary functions:

  1. It introduces an interface version of rand.Rand to allow better mocking (see xkcdrand for one such fake)
  2. It allows this interface to be created inline without importing both inlined/rand and math/rand in the same file.
  3. It allows the interface to be created with a goroutine-safe source, preserving the benefits of the package global math/rand methods.

The Rand interface implementations in this library are trivial wrappers around math/rand to avoid any loss of entropy. Since the library does not require a rand.Source in its constructors, callers should remember to always call Rand.Seed in production code. This is similar to the math/rand package methods, which also default to a seed of 1.

Usage

// Create an interface version of math/rand.Rand using the default (fixed) seed.
// Seeds can be changed with Rand.Seed.
rand.New()

// Create an interface version of math/rand.Rand that is goroutine safe, unlike
// math/rand.New()
rand.NewLocked()

Credit

lockedsource.go, while trivial, is inspired directly by the lockedSource type in math/rand/rand.go.

Documentation

Overview

Package rand allows developers to inject rand.Rand interfaces rather the math/rand.Rand struct. This allows for easier testing with two benefits:

  1. Developers can inject either a locking or unlocking Rand implementation (the built-in rand locks global methods and does not lock rand.Rand struct methods.
  2. The rand.Rand interface allows more straightforward faking. The built-in rand.Rand struct has differemt mechanisms for extracting various kinds of ints from bit fields, which can make fakes unnecessarily hard to create. For one such fake, see [xkcdrand](github.com/inlined/xkcdrand).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Deal

func Deal(r Rand, n, k int) []int

Deal selects k elements from n to k. It defaults to an O(n^2) implementation assuming n is small. deferrs to rand.(Dealer) if implemented.

func LockSource

func LockSource(s rand.Source) rand.Source

LockSource wrapps an existing rand.Source to make it goroutine safe.

Types

type Dealer

type Dealer interface {
	Deal(n, k int) []int
}

Dealer is an optional extension to Rand

type Rand

type Rand interface {
	ExpFloat64() float64
	Float32() float32
	Float64() float64
	Int() int
	Int31() int32
	Int31n(n int32) int32
	Int63() int64
	Int63n(n int64) int64
	Intn(n int) int
	NormFloat64() float64
	Perm(n int) []int
	Read(p []byte) (n int, err error)
	Seed(seed int64)
	Shuffle(n int, swap func(i, j int))
	Uint32() uint32
	Uint64() uint64
}

Rand is an injectable interface that matches the struct of math/rand.Rand

func New

func New() Rand

New creates a new rand interface implementation based backed by the rand.Rand struct. The returned value will not be goroutine safe. To get a goroutine safe implementation, use NewLocked().

func NewLocked

func NewLocked() Rand

NewLocked returns a goroutine safe implementation of the Rand interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL