请避免使用“因为语言规范如此规定”的答案/评论。该功能应该可以实现,而不会与当前的语法/语法冲突,并且将极大地帮助实现一致性和便利性。我知道这是一个哲学性的假设/为什么不是问题,但请忍受。
[Go语言具有我在大多数编程语言中都缺少的一个令人惊奇的功能:条件之前的init / assign语句。
if sec := time.Now().Second(); sec < 30 {
fmt.Printf("Seconds: %v\n", sec)
}
您可以在大多数语言中执行类似的操作,但是在Go语言中,变量仅存在于条件范围内,并且一旦出现障碍便不再存在。
现在,回到我的问题:你为什么不能这样做?
for sec := time.Now().Second(); sec < 30 {
fmt.Printf("Seconds: %v\n", sec)
}
澄清:应该在每次迭代评估条件之前立即执行init / assignment部分,以有效地使其成为条件的一部分。请不要被for
语句弄糊涂。这应该是它的“ while”形式,而不是标准的“ for”形式。
当然,您可以使用for
循环的“ while”形式执行此操作:
sec := time.Now().Second()
for sec < 30 {
fmt.Printf("Seconds: %v\n", sec)
sec = time.Now().Second()
}
但是,这会在外部作用域中显示sec
变量。因此,也许可以使用for
循环的传统“ for”形式:
for sec := time.Now().Second(); sec < 30; sec = time.Now().Second() {
fmt.Printf("Seconds: %v\n", sec)
}
尽管从技术上讲,这行之有效,但这远非完美。它更长,更丑陋,我认为它违反了DRY(两个工作版本)。当您想要修改分配的值时,您需要修改两位代码,这不是必需的。准确地说,当您忘记更改任何一项作业时,此类事情很容易出现易于标记,难以发现的错误。
[唯一的其他条件语言结构,switch
语句,像if
一样,支持init / pre-assignment语法。那么,为什么不for
呢?由于for
既是for
又是while
既令人困惑的性质,会被认为太令人困惑了吗?
使用if
编写的第一个switch
语句代码,用于功能说明:
switch sec := time.Now().Second(); {
case sec < 30:
fmt.Printf("Seconds: %v\n", sec)
}
即使在这里,sec
变量也存在于switch
内部,并且一旦离开其范围就不再存在。
是否有任何真正的原因没有实现一致性,而不是仅仅因为它“会令人困惑”?因为考虑到if
和switch
的现有语法,这种语法对我来说似乎非常直观。
您的特定语法无效,因为它不是语言规范的一部分。这也是不合逻辑的,这可能就是为什么它不在规范中的原因。
您只设置了一个变量,然后期望比较它的条件发生变化。
您应该做的是使用随时间变化的变量或表达式。也许像这样:
for time.Now().Second() < 30 {
fmt.Printf("second: %v\n", time.Now().Second())
time.Sleep(time.Second)
}
如果需要变量,只需确保对其进行更改:
for sec := time.Now().Second(); sec < 30; sec = time.Now().Second() {
fmt.Printf("second: %v\n", sec)
time.Sleep(time.Second)
}