为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在使用递归函数时会更新我的(初始)变量?

为什么在使用递归函数时会更新我的(初始)变量?

Go
泛舟湖上清波郎朗 2022-06-06 14:44:04
我决定在 go 中创建快速排序算法。我的快速排序代码是:package sortingfunc QuickSort(input []int) []int {    if len(input) <= 1 {        return input    }    sorted := input    pivotIndx := len(sorted) - 1 // The index of the last item of the array    pivot := sorted[pivotIndx]   // The value of the last item in the array    curLowIndx := 0    for indx, val := range sorted {        if val < pivot {            // Swap the items            sorted[indx], sorted[curLowIndx] = sorted[curLowIndx], sorted[indx]            // Increment the index on which the low position is stored.            // We need to do this so that the next item that is lower can be stored/swapped with the correct position            curLowIndx = curLowIndx + 1        }    }    sorted[curLowIndx], sorted[pivotIndx] = sorted[pivotIndx], sorted[curLowIndx]    // Sort the sub-arrays    QuickSort(sorted[:curLowIndx])    QuickSort(sorted[curLowIndx+1:])    return sorted}主文件代码:package mainimport (    "fmt"    "github.com/.../.../sorting")func main() {    // Sorting examples    toSort := []int{100, 20, 70, 30, 90, 40, 120, 123, 10, 23}    fmt.Println(toSort) // returns: [100 20 70 30 90 40 120 123 10 23]    shouldBeSorted := sorting.QuickSort(toSort)     fmt.Println(shouldBeSorted) // returns: [10 20 23 30 40 70 90 100 120 123]    fmt.Println(toSort) // ALSO returns: [10 20 23 30 40 70 90 100 120 123]}在我的主函数中,我在一个变量中有一个切片,我想对其进行排序(toSort)。我创建了一个新变量,我想在其中存储排序后的切片 ( shouldBeSorted)。但在这里我发现了一些我没有预料到,也没有理解的东西。当我调用sorting.QuickSort(toSort)它时,它会对其进行排序并将返回值分配给shouldBeSorted变量,但接下来它还会toSort使用来自sorting.QuickSort(toSort).我已经阅读了 go 中指针的用法,并且在传递指针时会出现这种行为,但在传递“常规”变量时不会。所以我的实际问题是:为什么会发生这种情况?为什么它会改变toSort变量?是不是我做错了什么或者这是预期的,为什么会这样?旁注:当递归发生时,它自身的 QuickSort 函数也会发生同样的事情:QuickSort(sorted[:curLowIndx])QuickSort(sorted[curLowIndx+1:])我首先认为我需要组合我将返回的切片,但显然它会更新原始排序切片。
查看完整描述

2 回答

?
LEATH

TA贡献1936条经验 获得超6个赞

Go 中的切片实际上由一个带有元信息的结构和一个指向存储实际数据的连续内存位置的指针组成。即使您toSort按值传递,复制的元结构仍然引用相同的底层内存位置。这就是为什么toSort也会改变。

如果您不希望这种情况发生,您可以使用 copy 创建一个新切片并将其传递。

切片内部:https ://blog.golang.org/slices-intro

复制:https ://golang.org/pkg/builtin/#copy


查看完整回答
反对 回复 2022-06-06
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

切片只是指向基础数据的指针,因此当您更新给定参数时,您正在更改实际数据。这就是您需要复制数据的原因:


func copySlice(s []int) []int {

    c := make([]int, len(s))

    copy(c, s)

    return c

}


func main() {

    toSort := []int{100, 20, 70, 30, 90, 40, 120, 123, 10, 23}

    sorted := sorting.QuickSort(copySlice(toSort))

    fmt.Println(toSort)

    fmt.Println(sorted)


查看完整回答
反对 回复 2022-06-06
  • 2 回答
  • 0 关注
  • 134 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信