douhan1860 2018-01-26 15:34
浏览 57

具有slice参数的golang函数不会修改原始容量

Why in go editing slice inside functions don't apply length update?

Fast response: because a slice is only a reference to the original array

As you can see in the following example, I have a slice that will be modified in the values by external function but the append operation is totally ignored until you return the value from the function and re-assign this to the original slice.

Working to improve the examples, I've added function that pass by reference and make modification operations to increase comfort about the solutions

package main

import (
    "fmt"

)
var sli = make([]int,8)

func main() {

    fmt.Println("START STATUS_____")
    fmt.Println("slice",sli)
    fmt.Println("   cap:", cap(sli))
    fmt.Println("   len:", len(sli))

    editSli(sli)
    fmt.Println("EDIT RESULT STATUS_____")
    fmt.Println("slice",sli)
    fmt.Println("   cap:", cap(sli))
    fmt.Println("   len:", len(sli))


    sli = updateSli(sli)
    fmt.Println("UPDATE RESULT STATUS_____")
    fmt.Println("slice",sli)
    fmt.Println("   cap:", cap(sli))
    fmt.Println("   len:", len(sli))

    sli = append(sli, 15, 16, 17)
    fmt.Println("DIRECT APPEND RESULT STATUS_____")
    fmt.Println("slice",sli)
    fmt.Println("   cap:", cap(sli))
    fmt.Println("   len:", len(sli))

    sli[13] = 99
    fmt.Println("DIRECT ASSIGNMENT OF LAST ELEMENT (13°) STATUS_____")
    fmt.Println("slice",sli)
    fmt.Println("   cap:", cap(sli))
    fmt.Println("   len:", len(sli))

    updateSliPointer(&sli)
    fmt.Println("
*** Finally, passing the slice as a pointer will modify the sctructure: ")
    fmt.Println("slice",sli)
    fmt.Println("   cap:", cap(sli))
    fmt.Println("   len:", len(sli))
}

func editSli(sliOrigin []int) {
    sliOrigin[7] = 11
    sliOrigin = append(sliOrigin, 33, 34, 35) //don't work
    fmt.Println("
inside the edit Slice function the sli is =", sliOrigin)
    fmt.Println("and the direct assignment of the last element (7°) ar right working.")
    fmt.Println("However, the slice append will not be applied to the original slice because this is an internal copy")
}

func updateSli(sliOrigin []int) []int{
    sliOrigin = append(sliOrigin, 12, 13, 14) //it works!
    fmt.Println("
inside the update Slice function the sli is = ", sliOrigin)
    fmt.Println("and this append will be applied to the original one becouse of the return value of this function is a new slice")
    return sliOrigin
}

func updateSliPointer(sliOrigin *[]int) {
    //don't work *sliOrigin[7] = 11
    *sliOrigin = append(*sliOrigin, 100, 101, 102)
    fmt.Println("
inside the UPDATE Slice POINTER function we have a sli pointer and we can modify directly the structures appending elements =", sliOrigin)
    fmt.Println("
but to access the values and modify it we have to create a local instance")
    var x = *sliOrigin
    x[4] = 9
}

Running this will produce:

START STATUS_____
slice [0 0 0 0 0 0 0 0]
    cap: 8
    len: 8

inside the edit Slice function the sli is = [0 0 0 0 0 0 0 11 33 34 35]
and the direct assignment of the last element (7°) ar right working.

However, the slice append will not be applied to the original slice because this is an internal copy
EDIT RESULT STATUS_____
    slice [0 0 0 0 0 0 0 11]
    cap: 8
    len: 8

inside the update Slice function the sli is =  [0 0 0 0 0 0 0 11 12 13 14]
and this append will be applied to the original one becouse of the return value of this function is a         new slice
UPDATE RESULT STATUS_____
    slice [0 0 0 0 0 0 0 11 12 13 14]
    cap: 16
    len: 11
DIRECT APPEND RESULT STATUS_____
    slice [0 0 0 0 0 0 0 11 12 13 14 15 16 17]
    cap: 16
    len: 14
DIRECT ASSIGNMENT OF LAST ELEMENT (13°) STATUS_____
    slice [0 0 0 0 0 0 0 11 12 13 14 15 16 99]
    cap: 16
    len: 14

inside the UPDATE Slice POINTER function we have a sli pointer and we can modify directly the         structures appending elements = &[0 0 0 0 0 0 0 11 12 13 14 15 16 99 100 101 102]

but to access the values and modify it we have to create a local instance

*** Finally, passing the slice as a pointer will modify the sctructure: 
    slice [0 0 0 0 9 0 0 11 12 13 14 15 16 99 100 101 102]
    cap: 32
    len: 17
  • 写回答

2条回答 默认 最新

  • doudou8893 2018-01-26 15:37
    关注

    editSli doesn't work because you're changing the capacity of the local copy of the slice and not returning it. Basically, your function must return the new slice for the exact same reason that append must return the updated slice; because if it has to increase capacity, it may have to use a new underlying array, and therefor any old reference to the slice will be invalid.

    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?