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

我决定在 go 中创建快速排序算法。


我的快速排序代码是:


package sorting


func 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 main


import (

    "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:])

我首先认为我需要组合我将返回的切片,但显然它会更新原始排序切片。


泛舟湖上清波郎朗
浏览 198回答 2
2回答

LEATH

Go 中的切片实际上由一个带有元信息的结构和一个指向存储实际数据的连续内存位置的指针组成。即使您toSort按值传递,复制的元结构仍然引用相同的底层内存位置。这就是为什么toSort也会改变。如果您不希望这种情况发生,您可以使用 copy 创建一个新切片并将其传递。切片内部:https ://blog.golang.org/slices-intro复制:https ://golang.org/pkg/builtin/#copy

宝慕林4294392

切片只是指向基础数据的指针,因此当您更新给定参数时,您正在更改实际数据。这就是您需要复制数据的原因:func copySlice(s []int) []int {&nbsp; &nbsp; c := make([]int, len(s))&nbsp; &nbsp; copy(c, s)&nbsp; &nbsp; return c}func main() {&nbsp; &nbsp; toSort := []int{100, 20, 70, 30, 90, 40, 120, 123, 10, 23}&nbsp; &nbsp; sorted := sorting.QuickSort(copySlice(toSort))&nbsp; &nbsp; fmt.Println(toSort)&nbsp; &nbsp; fmt.Println(sorted)}&nbsp;
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go