【问题标题】:Variable in for loop undefined outsidefor 循环中的变量在外部未定义
【发布时间】:2019-08-31 15:07:26
【问题描述】:

我想知道为什么以下代码不起作用:

package main

import (
    "fmt"
)

func main() {
    for i := 0; i < 10000; i++ {
        var randomString = fmt.Sprintf("a%sa\n", "test")
    }
    fmt.Printf("Made 10000 random strings like", randomString);
}

我已经删除了一些不相关的代码(因为这显然不是随机的)。

我遇到的问题是,在 for 循环下,“randomString”是未定义的。

我尝试使用 randomString := fmt.Sprintf() 和您在上面看到的 var 进行设置。

我很确定这是一个范围问题(randomString 变量不在 for 循环之外的范围内),但作为 PHP / JS 开发人员,我不习惯这个,我会说这个变量在 for 循环之后也可以使用。

我如何从那时访问该变量?基本上只是显示最后生成的字符串。

【问题讨论】:

    标签: go scope


    【解决方案1】:

    请参阅规范中的相关部分:Declarations and scope:

    在函数内声明的常量或变量标识符的范围从 ConstSpec 或 VarSpec(短变量声明的 ShortVarDecl)的末尾开始,在最里面的包含块的末尾结束

    在您要访问它的范围内定义它:在for 之前(在main() 函数的范围内)。

    还要注意fmt.Sprintf() 除了要打印的参数之外,还需要一个附加参数:格式字符串。要么提供一个格式字符串(例如,为 randomString 参数包含一个 %s 动词),要么你可以使用 fmt.Sprintln()

    func main() {
        var randomString string
        for i := 0; i < 10000; i++ {
            randomString = fmt.Sprintf("a%sa\n", "test")
        }
        fmt.Println("Made 10000 random strings like", randomString)
    }
    

    输出:

    Made 10000 random strings like atesta
    

    Go Playground 上试试。

    【讨论】:

    • 啊!这太明显了,我没看到。太好了,谢谢你:)
    • 确实,我忘记了格式化字符串中的 %s。但 Println 也适用于此。
    【解决方案2】:

    这是范围问题,在 Go 中 randomString 的范围是循环体,在 JS 中它将是整个函数。不同语言的范围规则不同。

    检查 Go 规范:

    https://golang.org/ref/spec#Declarations_and_scope

    【讨论】:

    • 谢谢,但我在提问之前检查了该页面 - 它并没有为我清除问题。我知道我有范围问题,所以我问了。
    • @RobQuist 这种情况的相关部分将是“在函数内声明的常量或变量标识符的范围开始于 ConstSpec 或 VarSpec(短变量声明的 ShortVarDecl)结束于最里面的包含块的结尾。"
    • 完全正确 :) 感谢您的努力!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多