for循环中变量的作用域

问题描述 投票:-1回答:1

以下程序处理两个数组。该算法没有什么意义,只是要注意数组tmp逐渐变小。

package main

import (
    "strings"
    "fmt"
)

func arrayToString(a []int, delim string) string {
    return strings.Trim(strings.Replace(fmt.Sprint(a), " ", delim, -1), "[]")
}

func numSeries(arr []int) ([]int, []int) {
    return arr[:2], arr[2:]
}

func main() {
    highnum := []int{8,7}
    tmp := []int{6,5,4,3,2,1}
    curr := []int{}
//    fRight := ""
    for i, v := range highnum {
        curr, tmp = numSeries(tmp)
        fmt.Printf("v %d numSeries result curr %s tmp %s\n", v, arrayToString(curr, ", " ), arrayToString(tmp, ", " ) )
        fmt.Printf("final (1) %s\n", arrayToString(tmp, ", " ) )       
//        fRight += "[" + arrayToString(append(curr, v), ", ") + "]"
        if i == len(highnum)-1 {
            fmt.Printf("final (2) %s\n", arrayToString(tmp, ", " ) )
        }
//        fmt.Printf("fRight |%s|\n", fRight)        

    }
}

结果是:

v 8 numSeries result curr 6, 5 tmp 4, 3, 2, 1
final (1) 4, 3, 2, 1
v 7 numSeries result curr 4, 3 tmp 2, 1
final (1) 2, 1
final (2) 2, 1

程序有效-输出中的final(1)和final(2)注释具有相同的值。但是,如果我取消注释上面的三个注释掉的语句,则会得到错误的结果。这是不正确的程序及其结果。

package main

import (
    "strings"
    "fmt"
)

func arrayToString(a []int, delim string) string {
    return strings.Trim(strings.Replace(fmt.Sprint(a), " ", delim, -1), "[]")
}

func numSeries(arr []int) ([]int, []int) {
    return arr[:2], arr[2:]
}

func main() {
    highnum := []int{8,7}
    tmp := []int{6,5,4,3,2,1}
    curr := []int{}
    fRight := ""
    for i, v := range highnum {
        curr, tmp = numSeries(tmp)
        fmt.Printf("v %d numSeries result curr %s tmp %s\n", v, arrayToString(curr, ", " ), arrayToString(tmp, ", " ) )
        fmt.Printf("final (1) %s\n", arrayToString(tmp, ", " ) )       
        fRight += "[" + arrayToString(append(curr, v), ", ") + "]"
        if i == len(highnum)-1 {
            fmt.Printf("final (2) %s\n", arrayToString(tmp, ", " ) )
        }
        fmt.Printf("fRight |%s|\n", fRight)        

    }
}

结果:

v 8 numSeries result curr 6, 5 tmp 4, 3, 2, 1
final (1) 4, 3, 2, 1
fRight |[6, 5, 8]|
v 7 numSeries result curr 8, 3 tmp 2, 1
final (1) 2, 1
final (2) 7, 1
fRight |[6, 5, 8][8, 3, 7]|

请注意,最终(1)和最终(2)注释具有不同的值。错了我怀疑这种行为是完全正确的,我很喜欢初学者的“陷阱”。如果有人可以指出一个现有的StackOverflow问题以提供解决方案或描述正在发生的事情,我将不胜感激。我特别高兴看到涉及此问题的官方语言定义的参考。

loops go scope
1个回答
0
投票

它在这里:

fRight += "[" + arrayToString(append(curr, v), ", ") + "]"

特别是append。这里的关键是切片是阵列上的视图。 currtmp指向相同的基础数组,curr是数组的开始部分,tmp是结尾。 append的工作方式是,如果切片具有足够的容量,则只需将元素添加到切片的末尾并增加len。运行append时,curr具有足够的容量,因此v被添加到curr的末尾,而这恰好是tmp的第一个元素。因此,您覆盖了该元素。

© www.soinside.com 2019 - 2024. All rights reserved.