Accessing Slice Values in a Map
When working with maps that contain slices as values, it's crucial to understand the implications of directly appending to the slice returned by the map accessor. As demonstrated in the example below, simply assigning the appended slice to the returned slice does not modify the underlying value in the map.
<code class="go">var aminoAcidsToCodons map[rune][]string for codon, aminoAcid := range utils.CodonsToAminoAcid { mappedAminoAcid := aminoAcidsToCodons[aminoAcid] // Return slice by value if ok := len(mappedAminoAcid) > 0; ok { // Check if slice is nil mappedAminoAcid = append(mappedAminoAcid, codon) // Create a new slice aminoAcidsToCodons[aminoAcid] = mappedAminoAcid // Reset map value } else { aminoAcidsToCodons[aminoAcid] = []string{codon} } }</code>
The issue stems from the fact that append returns a new slice if the underlying array needs to grow. Therefore, the following code does not work as intended:
<code class="go">mappedAminoAcid, ok := aminoAcidsToCodons[aminoAcid] if ok { mappedAminoAcid = append(mappedAminoAcid, codon) // Intended but incorrect }</code>
This behavior is similar to that of strings. For example:
<code class="go">var x map[string]string x["a"] = "foo" y := x["a"] // Copy string by value y = "bar" // x["a"] is still "foo" since a new string is created in y</code>
To resolve this issue and modify the map's underlying value, the appended slice must be reassigned to the corresponding map entry. Fortunately, a simpler approach exists: take advantage of the fact that a nil slice is a valid first argument for append.
<code class="go">aminoAcidsToCodons[aminoAcid] = append(aminoAcidsToCodons[aminoAcid], codon)</code>
The above is the detailed content of How to Modify Slice Values in a Map in Go?. For more information, please follow other related articles on the PHP Chinese website!