loops - for循环中的变量范围
问题描述
以下程序操作两个数组。该算法并不重要,只是要注意数组 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
该程序有效 - 输出中的最终 (1) 和最终 (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 问题来提供解决方案或描述正在发生的事情,我将不胜感激。我特别高兴看到对涵盖此问题的官方语言定义的引用。
解决方案
是这里:
fRight += "[" + arrayToString(append(curr, v), ", ") + "]"
特别是,append
。这里的关键是切片是数组上的视图。curr
andtmp
指向同一个底层数组,作为它的curr
开始部分和tmp
结束部分。可行的方法append
是,如果切片有足够的容量,它将简单地将元素添加到切片的末尾并增加len
. 当你运行它时append
,curr
有足够的容量,所以v
被添加到 的末尾curr
,这恰好是 的第一个元素tmp
。所以你覆盖了那个元素。
推荐阅读
- python - Kivy - 我看不到图片
- javascript - 为什么我可以将 es6 导入仅用于生成 commonJS 和 UMD 包的库?
- html - 使用元视口丢失文本
- java - 无法在 codechef ide 中运行程序。得到 CodeChef NZEC 错误
- java - 一次又一次调用paint方法,并且该过程在Applet中没有停止,并且重新绘制了十六进制并且我丢失了所有数字
- c - malloc() 和 realloc() 函数的奇怪行为导致分段错误
- python - Google Foobar 问题 - Python 测试用例失败
- react-native - React-native:如何禁用开发工具 webbrowser 选项卡的打开?
- javascript - 单击按钮时在对话框中显示结果
- google-cloud-storage - 我需要将 Blob 的哪些部分存储在我的数据库中以检索回文件?