Documentation ¶
Overview ¶
Package unsafeslice implements common unsafe transformations involving slices.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AsString ¶
AsString returns a string that refers to the data backing the slice s.
The caller must ensure that the contents of the slice are never again mutated, and that its memory either is managed by the Go garbage collector or remains valid for the remainder of this process's lifetime.
Programs that use AsString should be tested under the race detector to flag erroneous mutations.
Programs that have been adequately tested and shown to be safe may be recompiled with the "unsafe" tag to significantly reduce the overhead of this function, at the cost of reduced safety checks. Programs built under the race detector always have safety checks enabled, even when the "unsafe" tag is set.
Example ¶
package main import ( "fmt" "hash/fnv" "io" "github.com/bcmills/unsafeslice" ) func main() { const input = "Hello, world!" h := fnv.New64a() io.WriteString(h, input) // Save the computed checksum as an immutable string, // without incurring any additional allocations or copying // (beyond the slice for the Sum output). binaryChecksum := unsafeslice.AsString(h.Sum(nil)) fmt.Printf("%x\n", binaryChecksum) }
Output: 38d1334144987bf4
func ConvertAt ¶
func ConvertAt(dst, src interface{})
ConvertAt sets dst, which must be a non-nil pointer to a variable of a slice type, to a slice that refers to the same memory region as the slice src, but possibly at a different type.
The caller must ensure that src meets the alignment requirements for dst, and that the length and capacity of src are integer multiples of the element size of dst.
This implements one possible API for https://golang.org/issue/38203.
Example ¶
package main import ( "fmt" "github.com/bcmills/unsafeslice" ) func main() { // For this example, we're going to do a transformation on some ASCII text. // That transformation is not endian-sensitive, so we can reinterpret the text // as a slice of uint32s to process it word-at-a-time instead of // byte-at-a-time. const input = "HELLO, WORLD!" // Allocate an aligned backing buffer. buf := make([]uint32, (len(input)+3)/4) // Reinterpret it as a byte slice so that we can copy in our text. var alias []byte unsafeslice.ConvertAt(&alias, buf) copy(alias, input) // Perform an endian-insensitive transformation word-by-word instead of // byte-by-byte. for i := range buf { buf[i] |= 0x20202020 } // Read the result back out of the byte-slice view to interpret it as text. fmt.Printf("%s\n", alias[:len(input)]) }
Output: hello, world!
func OfString ¶
OfString returns a slice that refers to the data backing the string s.
The caller must ensure that the contents of the slice are never mutated.
Programs that use OfString should be tested under the race detector to flag erroneous mutations.
Programs that have been adequately tested and shown to be safe may be recompiled with the "unsafe" tag to significantly reduce the overhead of this function, at the cost of reduced safety checks. Programs built under the race detector always have safety checks enabled, even when the "unsafe" tag is set.
Example ¶
package main import ( "fmt" "hash" "hash/fnv" "github.com/bcmills/unsafeslice" ) func main() { s := "Hello, world!" // Temporarily view the string s as a slice, // so that we can compute its checksum with an arbitrary hash.Hash // implementation without needing to copy it. var h hash.Hash = fnv.New64a() b := unsafeslice.OfString(s) // This is safe because the contract for an io.Writer requires that // “Write must not modify the slice data, even temporarily.” h.Write(b) fmt.Printf("%x\n", h.Sum(nil)) }
Output: 38d1334144987bf4
func SetAt
deprecated
SetAt sets dst, which must be a non-nil pointer to a variable of a slice type, to a slice of length and capacity n located at p.
The caller must ensure that p meets the alignment requirements for dst, and that the allocation to which p points contains at least n contiguous elements.
This implements one possible API for https://golang.org/issue/19367 and https://golang.org/issue/13656.
Deprecated: as of Go 1.17, use unsafe.Slice instead.
Example ¶
package main import ( "fmt" "unsafe" "github.com/bcmills/unsafeslice" ) // asCPointer returns b as a C-style pointer and length func asCPointer(b []byte) (*byte, int) { if len(b) == 0 { return nil, 0 } return &b[0], len(b) } func main() { original := []byte("Hello, world!") p, n := asCPointer(original) var alias []byte unsafeslice.SetAt(&alias, unsafe.Pointer(p), n) fmt.Printf("original: %s\n", original) fmt.Printf("alias: %s\n", alias) copy(alias, "Adios") fmt.Printf("original: %s\n", original) fmt.Printf("alias: %s\n", alias) }
Output: original: Hello, world! alias: Hello, world! original: Adios, world! alias: Adios, world!
Types ¶
This section is empty.
Directories ¶
Path | Synopsis |
---|---|
internal
|
|
eventually
Package eventually enables the use of finalizers whose registration can be blocked until an arbitrary point in the program.
|
Package eventually enables the use of finalizers whose registration can be blocked until an arbitrary point in the program. |