英文:
'declared and not used' because Go compiler can't consider loops?
问题
标题不好,但我不知道如何在字符限制内以其他方式描述它。
作为一个学习练习,我正在尝试编写一个小的Go程序来模拟彩票抽奖。它会抽取六个随机数作为中奖号码,然后不断地抽取随机的整数数组,直到再次抽到中奖号码为止。
首先,我编写了一个函数,该函数接受一个通道,并无限循环地将“包含6个随机整数的数组”添加到通道中:
func draw(ch chan<- [6]int) {
generator := rand.New(rand.NewSource(time.Now().UnixNano()))
for {
ch <- [6]int{
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
}
}
}
然后在main()
函数中,我指定了两个操作系统线程,创建了一个可以容纳250个包含6个整数的数组的通道,并在一个goroutine中启动了我的draw()
函数。
runtime.GOMAXPROCS(2)
ch := make(chan [6]int, 250)
go draw(ch)
接下来,我从通道中获取一个中奖号码(例如[4 8 15 16 23 42]
),然后获取一个“当前”号码,即最近一次抽奖的号码。我将游戏次数计数器设置为1:
winning := <- ch
current := <- ch
games_played := 1
这里是棘手的部分。
在一个无限循环中,我检查当前抽奖号码是否等于中奖号码。如果是,我打印出游戏次数,并跳出循环。
如果不是,我将current
设置为一个新的抽奖号码,并增加计数器。然后,循环应该再次运行if winning == current...
的检查,直到找到匹配为止。
for {
if winning == current {
fmt.Println(games_played)
break
} else {
current := <- ch
games_played += 1
}
}
问题在于:倒数第四行的current := <- ch
会引发编译错误,错误信息为“current被声明但未使用”。我想说:“是的,我知道在该点向下读取后它不再使用,但它在循环内部声明,所以它的值在下一次迭代中是重要的。”但我无法弄清楚如何解决这个问题,或者是否犯了什么愚蠢的错误。显然,我对Go一无所知。但是对我来说,经过思考,逻辑是正确的。我是不是搞错了什么?
(注意:我知道忽略了一个问题,即抽取的号码[1 2 3]
与[2 3 1]
不相等,现在先忽略这个问题。)
英文:
Poor title, but I didn't know how else to describe it within the character limit.
As a learning exercise, I'm trying to write a little Go program that simulates a lottery draw. It draws six random numbers to be the winning set, then continually draws random arrays of random ints until you get that set again.
First I wrote a function which takes a channel and infinitely loops "add array of 6 random ints to the channel":
func draw(ch chan<- [6]int) {
generator := rand.New(rand.NewSource(time.Now().UnixNano()))
for {
ch <- [6]int{
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
generator.Intn(100),
}
}
}
Then in main()
I specify two OS threads, create a channel that can hold 250 arrays of 6 ints, and start my draw()
function in a goroutine.
runtime.GOMAXPROCS(2)
ch := make(chan [6]int, 250)
go draw(ch)
Next I take a winning set (eg [4 8 15 16 23 42]
) from the channel, then a 'current' set, meaning the most recent draw. I set my game_played counter to 1:
winning := <- ch
current := <- ch
games_played := 1
Here's the tricky bit.
In an infinite loop, I check if the current draw is equal to the winning draw. If it is, I print the number of games played, and break from the loop.
If it isn't, I set current
to a new draw, and increment the counter. The loop should then run the if winning == current...
check again over and over until there's a match.
for {
if winning == current {
fmt.Println(games_played)
break
} else {
current := <- ch
games_played += 1
}
}
Here's the problem: that fourth-last line, current := <- ch
, throws a compiler error, 'current declared and not used'. I want to say "Yeah, I know it's not used after that point reading downward, but it's declared inside a loop, so its value matters on the next iteration." But I can't work out how, or if I've done something stupid. I'm totally clueless about Go, obviously. But to me, thinking through it, the logic is sound. Am I messing something up?
(Note: I'm aware of the oversight that a draw of [1 2 3]
won't be equal to [2 3 1]
, ignoring that for now.)
答案1
得分: 6
第二个current
变量在if
作用域中。将current := <- ch
替换为current = <- ch
(没有冒号)。使用:=
会在嵌套作用域中定义一个新的current
变量。
if winning == current {
fmt.Println(games_played)
break
} else {
current := <- ch
games_played += 1
}
等同于:
if winning == current {
fmt.Println(games_played)
break
} else {
var current int[6] // 你不想要这个,因为它会遮蔽外部作用域中的current
current = <- ch // 你只想要这个
games_played += 1
}
英文:
The second current is in the if
scope. Replace current := <- ch
with current = <- ch
(no colon). When using :=
you define a new current
variable in the nested scope.
if winning == current {
fmt.Println(games_played)
break
} else {
current := <- ch
games_played += 1
}
is equivalent of:
if winning == current {
fmt.Println(games_played)
break
} else {
var current int[6] // you don't want this, as it shadows your
// current form the outher scope
current = <- ch // you want only this guy
games_played += 1
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论