In Go, the preferred method for converting a byte slice ([]byte) to a string is:
<code class="go">var b []byte // fill b s := string(b)</code>
This approach facilitates byte slice copying, which might prove problematic in performance-critical situations.
However, for such scenarios, an unsafe conversion can be considered:
<code class="go">var b []byte // fill b s := *(*string)(unsafe.Pointer(&b))</code>
Consequences of Unsafe Conversion
While unsafe conversion can indeed enhance performance, it risks violating the immutability guarantee of strings in Go. Modifying a string that the language specification expects to be immutable can lead to unexpected behavior. The following are some potential consequences:
<code class="go">m := map[string]int{} b := []byte("hi") s := *(*string)(unsafe.Pointer(&b)) m[s] = 999 fmt.Println("Before:", m) b[0] = 'b' fmt.Println("After:", m) fmt.Println("But it's there:", m[s], m["bi"]) for i := 0; i < 1000; i++ { m[strconv.Itoa(i)] = i } fmt.Println("Now it's GONE:", m[s], m["bi"]) for k, v := range m { if k == "bi" { fmt.Println("But still there, just in a different bucket: ", k, v) } }</code>
After modifying the string's first byte to 'b', it becomes unfindable using either the original or modified key. However, the modified string still exists in the map, albeit in a different bucket.
The above is the detailed content of ## When and Why Should You Avoid `unsafe` Conversion from `[]byte` to `string` in Go?. For more information, please follow other related articles on the PHP Chinese website!