Go how to properly use the for … range loop

huangapple go评论79阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2016年1月6日 23:32:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/34636862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定