我还是编程新手。原谅我缺乏计算机科学知识。不确定这个问题是不是专门针对Golang或一般的计算机科学...
我一直认为,函数不会更改其自身作用域之外的变量/数据,除非您在其他作用域中使用return语句,或者它们在作用域的层次结构中较高。有人可能会争辩说,此示例中的函数f1f2是从较低范围调用的。但是,这仍然不能解释为什么我对于变量numnums会得到不同的结果。

package main

import "fmt"

func f1(a int) {
    a = 50 // this will not work, as it shouldn't
}

func f2(a ...int) {
    a[0] = 50 // this will work without return statement
    a[1] = 50 // this will work without return statement
}

func main() {

    num := 2
    nums := []int{2, 2}

    f1(num)
    f2(nums...)

    fmt.Printf("function f1 doesn't affect the variable num and stays: %v\n", num)
    fmt.Printf("function f2 affects the variable nums and results in: %v", nums)
问题:
  • 为什么f2不需要return语句来修改num之类的num
    会在f1中吗?
  • 据说
  • Golang函数传递值(而不是引用),
    那不应该强迫函数返回副本吗?
  • 可以使用其他语言吗? (我想我可能有
    看到其他语言)。
  • 最佳答案

    这是正确的行为,因为a ...int等于 slice ,例如:a []int

    func f2(a []int) {
        a[0] = 50
        a[1] = 50
    }
    func main() {
        b := []int{2, 2}
        f2(b)
        fmt.Println(b) // [50 50]
    }
    
    slice 是原始数据(这里为“b”)的视图。

    “为什么f2不需要return语句来像num一样修改f1中的num?”

    f2中,您使用的是 slice ,该 slice 具有指向原始数组的指针,因此f2可以更改外部数组。

    “据说Golang函数传递值(不是引用),这不应该强制返回副本吗?(如果问题与之相关...)”

    f2中, slice 本身通过值传递,这意味着指针以及原始数组的长度和容量。

    “这可以用其他语言发生吗?(我想我可能已经用其他语言看到过)”

    回答范围太广,有许多种语言,总的来说,如果您有一个指向外界数组的指针,是的。

    编辑:
    package main
    
    import "fmt"
    
    func sum(a ...int) int {
        s := 0
        for _, v := range a {
            s += v
        }
        return s
    }
    func f2(a []int) {
        c := make([]int, len(a))
        copy(c, a)
        c[0] = 50
        fmt.Println(sum(c...)) // 52
    }
    func main() {
        b := []int{2, 2}
        fmt.Println(sum(1, 2, 3, 4)) // 10
        fmt.Println(sum(b...))       // 4
    
        f2(b)
        fmt.Println(b) // [2 2]
    }
    
    笔记:
    上面的sum()函数是纯函数,因为它没有副作用。
    上面的新f2函数是纯函数,因为它没有副作用:它将a的副本复制到c中,然后调用求和。

    关于go - slice 或数组是否充当全局作用域?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62645072/

    10-13 04:23