为什么没有for(while)循环的初始化版本

问题描述 投票:-2回答:1

请避免使用“因为语言规范如此规定”的答案/评论。该功能应该可以实现,而不会与当前的语法/语法冲突,并且将极大地帮助实现一致性和便利性。我知道这是一个哲学性的假设/为什么不是问题,但请忍受。

[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内部,并且一旦离开其范围就不再存在。

是否有任何真正的原因没有实现一致性,而不是仅仅因为它“会令人困惑”?因为考虑到ifswitch的现有语法,这种语法对我来说似乎非常直观。

for-loop go while-loop language-design
1个回答
0
投票

您的特定语法无效,因为它不是语言规范的一部分。这也是不合逻辑的,这可能就是为什么它不在规范中的原因。

您只设置了一个变量,然后期望比较它的条件发生变化。

您应该做的是使用随时间变化的变量或表达式。也许像这样:

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)
}
© www.soinside.com 2019 - 2024. All rights reserved.