我在程序中看到了与程序中此特定循环相关的不同行为,但我不确定我为什么理解它的行为方式。
//global variable
var cmds = []string {
"create",
"delete",
"update",
}
func loop1() {
actions := make(map[string]func())
for _, cmd := range cmds {
actions[cmd] = func() {
fmt.Println(cmd)
}
}
for _, action := range actions {
action()
}
}
func loop2() {
actions := make(map[string]func())
for i, cmd := range cmds {
command := cmds[i]
actions[cmd] = func() {
fmt.Println(command)
}
}
for _, action := range actions {
action()
}
}
的输出loop1()
是
update
update
update
的输出loop2()
是
delete
update
create
我去网上看了以下内容
在切片上进行测距时,每次迭代都会返回两个值。第一个是索引,第二个是该索引处的元素的副本
它说一个副本,这是否意味着它返回了html" target="_blank">字符串的副本,但这实际上是指向变量的指针cmd
?在这种情况下cmd
,在循环结束时对will的任何引用都实际上引用了数组中的最后一个元素,例如update
?这是否意味着使用该range
方法时,数组的元素应该始终由其索引引用,并且由于它总是更新指针,因此使用它返回的元素的用例是什么?
问题loop1()
在于您将函数文字存储在actions
引用 循环变量
的映射中cmd
。该循环变量只有一个实例,因此在循环后调用actions
映射中存储的函数时,所有实例都将引用此单个循环变量(之所以保留,是因为函数/闭包仍然引用了该变量),但是它
在执行 时的值将是for
循环设置的最后一个值,即cmds
切片中的最后一个值(即"update"
,因此您将看到"update"
打印3次)。
一个简单的解决方法是制作此循环变量的副本,因此,每次迭代,每个函数文字都将有其自己的副本,该副本与循环变量“分离”:
func loop1() {
actions := make(map[string]func())
for _, cmd := range cmds {
cmd2 := cmd
actions[cmd] = func() {
fmt.Println(cmd2) // Refer to the detached, copy variable!
}
}
for _, action := range actions {
action()
}
}
这样,输出loop1()
(在Go Playground上尝试):
update
create
delete
这不是的问题for ... range
,这是因为闭包引用的是同一个变量,并且您不会仅在循环之后立即使用变量的值。当您打印此变量的值时,所有变量都将打印相同的最后一个值。
我可以打印最大罚款,但我不能打印计数。我看不出max和count之间的区别,也看不出为什么它不让我打印count。感谢任何帮助
问题内容: 通过测试我发现 这是不合法的: 但这是: 为什么? 问题答案: 第一种方法不合法,因为编译器很明显不能使用在那里声明的声明,因为在该循环中不能再包含其他语句。基本上,该位置的新变量声明将超出下一个语句的范围,因此没有任何用处。 在第二种情况下,循环后跟花括号,这创建了一个新的作用域,您可以使用该变量。
当用户键入以下内容的答案时:system.out.println(“键入数字”); 它不会继续到我的代码的下一部分。
问题内容: 我想做的是请用户输入一些字符串以读入数组,然后要求用户输入该数量的字符串并将其读入数组。当我运行此代码时,它从不要求我在第一个for循环的第一个循环中输入内容,只打印出“字符串#0:字符串#1:”,然后我就可以输入文本了。为什么会这样,我做错了什么? 问题答案: 缓冲。 输入输入数量时,不会在输入缓冲区中占用换行符的位置。在for循环的迭代0中,缓冲区中已经有一行输入,并且可以立即完成
在我的程序中,我发现当为时,循环无法正确退出。它看起来像整数溢出,远远大于10,循环不会停止。请告诉我发生了什么,以及如何在大型项目中避免这个错误。 代码链接
如下所示,我要反转数组。但我的代码不管用。这是我的for循环。请看一下。这个for循环正确吗。代码如下。