golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/slog/value_119.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.19 && !go1.20 6 7 package slog 8 9 import ( 10 "reflect" 11 "unsafe" 12 ) 13 14 type ( 15 stringptr unsafe.Pointer // used in Value.any when the Value is a string 16 groupptr unsafe.Pointer // used in Value.any when the Value is a []Attr 17 ) 18 19 // StringValue returns a new Value for a string. 20 func StringValue(value string) Value { 21 hdr := (*reflect.StringHeader)(unsafe.Pointer(&value)) 22 return Value{num: uint64(hdr.Len), any: stringptr(hdr.Data)} 23 } 24 25 func (v Value) str() string { 26 var s string 27 hdr := (*reflect.StringHeader)(unsafe.Pointer(&s)) 28 hdr.Data = uintptr(v.any.(stringptr)) 29 hdr.Len = int(v.num) 30 return s 31 } 32 33 // String returns Value's value as a string, formatted like fmt.Sprint. Unlike 34 // the methods Int64, Float64, and so on, which panic if v is of the 35 // wrong kind, String never panics. 36 func (v Value) String() string { 37 if sp, ok := v.any.(stringptr); ok { 38 // Inlining this code makes a huge difference. 39 var s string 40 hdr := (*reflect.StringHeader)(unsafe.Pointer(&s)) 41 hdr.Data = uintptr(sp) 42 hdr.Len = int(v.num) 43 return s 44 } 45 return string(v.append(nil)) 46 } 47 48 // GroupValue returns a new Value for a list of Attrs. 49 // The caller must not subsequently mutate the argument slice. 50 func GroupValue(as ...Attr) Value { 51 hdr := (*reflect.SliceHeader)(unsafe.Pointer(&as)) 52 return Value{num: uint64(hdr.Len), any: groupptr(hdr.Data)} 53 }