Golang中将字符串数组(非引用)复制到map的方法

Golang中将字符串数组(非引用)复制到map的方法 我正在尝试找到一种方法将HTML表格数据排序到某种数组或映射中,以便能够实现类似以下功能:

package main

import "fmt"

func main() {
    rows := make(map[string][]string)
    row := []string{"this","is","a","row"}
    rows["test"] = row[:]
    row = row[:0]
    row = append(row,"another")
    row = append(row,"test")
    row = append(row,"of")
    row = append(row,"rows")
    rows["another"] = row[:]
    fmt.Println(rows)
}

问题在于它似乎复制的是对row的引用而不是值,所以当我运行这段代码时,最终得到的结果是:

map[another:[another test of rows] test:[another test of rows]]

如何复制实际的内容?

谢谢


更多关于Golang中将字符串数组(非引用)复制到map的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

感谢两位。这对我帮助很大。

罗伯

更多关于Golang中将字符串数组(非引用)复制到map的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


其实你并不需要使用 row[:],它只是表示切片的全部内容。你可以直接使用 row。如下所示:

package main

import (
	"fmt"
)

func main() {
	row := []int{1, 2, 3}
	fmt.Println(row)
}

这是因为切片共享相同的底层数组。你可以使用 copy 来创建一个新的切片,例如:

rows["test"] = make([]string, 4)
copy(rows["test"], row[:])

在 Playground 上尝试:https://play.golang.org/p/Ppgv6_t88PJ

您遇到的问题是由于切片在Go语言中是引用类型,当您使用 row[:] 时,实际上是在传递对底层数组的引用,而不是复制数据。当您修改 row 后,之前存储在 rows 中的值也会随之改变,因为它们共享同一个底层数组。

要复制字符串切片的内容,您需要显式地创建一个新的切片并复制所有元素。以下是几种解决方案:

方法1:使用 append 复制切片

package main

import "fmt"

func main() {
    rows := make(map[string][]string)
    row := []string{"this", "is", "a", "row"}
    
    // 使用 append 复制切片内容
    rows["test"] = append([]string(nil), row...)
    
    row = row[:0]
    row = append(row, "another")
    row = append(row, "test")
    row = append(row, "of")
    row = append(row, "rows")
    
    // 再次使用 append 复制
    rows["another"] = append([]string(nil), row...)
    
    fmt.Println(rows)
}

方法2:使用 copy 函数

package main

import "fmt"

func main() {
    rows := make(map[string][]string)
    row := []string{"this", "is", "a", "row"}
    
    // 创建新切片并使用 copy
    testCopy := make([]string, len(row))
    copy(testCopy, row)
    rows["test"] = testCopy
    
    row = row[:0]
    row = append(row, "another")
    row = append(row, "test")
    row = append(row, "of")
    row = append(row, "rows")
    
    // 再次复制
    anotherCopy := make([]string, len(row))
    copy(anotherCopy, row)
    rows["another"] = anotherCopy
    
    fmt.Println(rows)
}

方法3:使用辅助函数简化复制过程

package main

import "fmt"

// 复制字符串切片的辅助函数
func copyStringSlice(src []string) []string {
    dst := make([]string, len(src))
    copy(dst, src)
    return dst
}

func main() {
    rows := make(map[string][]string)
    row := []string{"this", "is", "a", "row"}
    
    rows["test"] = copyStringSlice(row)
    
    row = row[:0]
    row = append(row, "another")
    row = append(row, "test")
    row = append(row, "of")
    row = append(row, "rows")
    
    rows["another"] = copyStringSlice(row)
    
    fmt.Println(rows)
}

所有这三种方法都会产生正确的输出:

map[another:[another test of rows] test:[this is a row]]

推荐使用方法1或方法3,因为它们代码更简洁。方法1使用 append([]string(nil), row...) 是最常用的方式,它创建一个新的空切片并将原切片的所有元素追加进去,从而完成复制。

回到顶部