golang copy 函數(shù)的使用

之前用 copy 不多,本以為它是個(gè)很方便的函數(shù),沒(méi)想到在做練習(xí)題時(shí)竟還是被它坑了。是我對(duì)他期望太多了。

func copy(dst, src []Type) int

基本認(rèn)識(shí):

  • 它只能用于切片,不能用于 map 等任何其他類(lèi)型
  • 它返回結(jié)果為一個(gè) int 型值,表示 copy 的長(zhǎng)度

坑位一:切片 dst 需要先初始化長(zhǎng)度

不是你定義好類(lèi)型,就能將 src 完全 copy 到 dst 的,你需要初始化長(zhǎng)度。

  • 如果 dst 長(zhǎng)度小于 src 的長(zhǎng)度,則 copy 部分;
  • 如果大于,則全部拷貝過(guò)來(lái),只是沒(méi)占滿(mǎn) dst 的坑位而已;
  • 相等時(shí)剛好不多不少 copy 過(guò)來(lái)。

坑位二:源切片中元素類(lèi)型為引用類(lèi)型時(shí),拷貝的是引用

由于只 copy 切片中的元素,所以如果切片元素的類(lèi)型是引用類(lèi)型,那么 copy 的也將是個(gè)引用。

如下面例子,matA 和 matB 地址不一樣,但 matA[0] 和 matB[0] 的地址是一樣的。

func wrongCopyMatrix() {
    matA := [][]int{
        {0, 1, 1, 0},
        {0, 1, 1, 1},
        {1, 1, 1, 0},
    }
    matB := make([][]int, len(matA))
    copy(matB, matA)
    fmt.Printf("%p, %p\n", matA, matA[0]) // 0xc0000c0000, 0xc0000c2000
    fmt.Printf("%p, %p\n", matB, matB[0]) // 0xc0000c0050, 0xc0000c2000
}

如果想 copy 多維切片中的每一個(gè)切片類(lèi)型的元素,那么你需要將每個(gè)切片元素進(jìn)行 初始化拷貝。注意是兩步:先 初始化,再 拷貝。

正確的拷貝一個(gè)多維數(shù)組:

func rightCopyMatrix() {
    matA := [][]int{
        {0, 1, 1, 0},
        {0, 1, 1, 1},
        {1, 1, 1, 0},
    }
    matB := make([][]int, len(matA))
    for i := range matA {
        matB[i] = make([]int, len(matA[i])) // 注意初始化長(zhǎng)度
        copy(matB[i], matA[i])
    }
    fmt.Printf("%p, %p\n", matA, matA[0]) // 0xc00005c050, 0xc000018560
    fmt.Printf("%p, %p\n", matB, matB[0]) // 0xc00005c0a0, 0xc0000185c0
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容