英文:
Go how to properly use the for ... range loop
问题
目前,还没有类似于您提到的&range
标签的语言特性。不过,您可以通过使用range
循环的索引值来简化代码,而无需每次都使用m := &ms[i]
。以下是修改后的代码示例:
package main
import (
"time"
"minions/minion"
)
func main() {
// 创建切片
ms := make([]*minion.Minion, 2)
// 填充切片并让元素开始执行任务
for i := range ms {
ms[i] = minion.NewMinion()
ms[i].Start()
}
// 等待所有任务完成
time.Sleep(time.Millisecond * 500)
// 停止切片中的元素执行任务
for _, m := range ms {
m.Stop()
}
}
在这个修改后的代码中,我们直接将minion.NewMinion()
的返回值赋给了ms[i]
,而不再使用m := &ms[i]
。这样可以更简洁地处理循环中的元素。希望这样的修改能够减少您的编码工作量。
英文:
At the moment I have a go program that contains the following code.
package main
import "time"
import "minions/minion"
func main() {
// creating the slice
ms := make([]*minion.Minion, 2)
//populating the slice and make the elements start doing something
for i := range ms {
m := &ms[i]
*m = minion.NewMinion()
(*m).Start()
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for i := range ms {
m := &ms[i]
(*m).Stop()
}
}
Here NewMinion()
is a constructor that returns a *minion.Minion
The code works perfectly, but having to write m := &ms[i]
every time I use a for ... range
loop seems to me like there should be a code writer friendlier way to tackle this problem.
Ideally I'd like something like the following to be possible (using the made up &range tag):
package main
import "time"
import "minions/minion"
func main() {
// creating the slice
ms := make([]*minion.Minion, 2)
//populating the slice and make the elements start doing something
for _, m := &range ms {
*m = minion.NewMinion()
(*m).Start()
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for _, m := &range ms {
(*m).Stop()
}
}
Unfortunately, this is not a language feature as of yet. Any considerations on what would be the nicest way remove the m := &ms[i]
from the code? Or is there no way yet that takes less effort to write than this?
答案1
得分: 3
你的第一个示例是一个指针切片,你不需要在切片中取指针的地址,然后每次解引用指针。更符合Go语言习惯的写法如下(稍作修改以在playground中运行,不需要"minion"包):
// 创建切片
ms := make([]*Minion, 2)
// 填充切片并让元素开始执行任务
for i := range ms {
ms[i] = NewMinion(i)
ms[i].Start()
// (或者等价地)
// m := NewMinion(i)
// m.Start()
// ms[i] = m
}
// 等待所有小兵完成工作
time.Sleep(time.Millisecond * 500)
// 让切片中的元素停止当前任务
for _, m := range ms {
m.Stop()
}
希望对你有帮助!
英文:
Your first example is a slice of pointers, you don't need to take the address of the pointers in the slice and then dereference the pointers each time. More idiomatic Go would look like (edited slightly to run in the playground without the "minion" package):
http://play.golang.org/p/88WsCVonaL
// creating the slice
ms := make([]*Minion, 2)
//populating the slice and make the elements start doing something
for i := range ms {
ms[i] = NewMinion(i)
ms[i].Start()
// (or equivalently)
// m := MewMinion(i)
// m.Start()
// ms[i] = m
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for _, m := range ms {
m.Stop()
}
答案2
得分: 0
这完全是错的。
在你的代码中,没有必要获取指针的地址。ms
是一个指针的切片,而你的构造函数返回一个指针,所以直接将 i
赋值给它就可以了:
for i := range ms {
ms[i] = minion.NewMinion()
ms[i].Start()
}
非常简单。
英文:
This is all wrong.
There is absolutely no need to take the address of a pointer in your code. ms
is a slice of pointers and you constructor returns a pointer so just assign i directly:
for i := range ms {
ms[i] = minion.NewMinion()
ms[i].Start()
}
Dead simple.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论