【问题标题】:Redeclare a variable from a different block in a short variable declaration在短变量声明中重新声明来自不同块的变量
【发布时间】:2011-02-18 07:12:36
【问题描述】:

如何在短变量声明中重新声明来自不同块的变量?

func f() (err os.Error) {
    proc, err := os.StartProcess(blah blah blah)
    // the new err masks the return value?
}

有一个long threadissue 讨论这个问题,但我暂时对如何解决这个问题很感兴趣。

【问题讨论】:

    标签: scope go


    【解决方案1】:

    short variable declarations 的 Go 规范很明确:

    一个简短的变量声明可以 重新声明变量,前提是它们是 最初在同一个块中声明 具有相同的类型,并且至少有一个 的非空白变量是新的。

    因此,在简短的变量声明中,您不能重新声明最初在不同块中声明的变量。

    下面是一个示例,说明如何通过在内部块中声明一个局部变量 (e) 并将其 (e) 分配给在外部块中声明的变量 (err2) 来绕过此限制。

    package main
    
    import (
        "fmt"
        "os"
    )
    
    func f() (err1 os.Error, err2 os.Error) {
        fi, err1 := os.Stat("== err1 os.Error ==")
        _ = fi
        {
            fi, e := os.Stat("== e os.Error ==")
            _ = fi
            err2 = e
        }
        return
    }
    
    func main() {
        err1, err2 := f()
        fmt.Println("f() err1:", err1)
        fmt.Println("f() err2:", err2)
    }
    

    输出:

    f() err1: stat == err1 os.Error ==: no such file or directory
    f() err2: stat == e os.Error ==: no such file or directory
    

    这是前面的示例重写为使用显式常规 variable declarations 并命名为 function parameters 而不是隐式 short variable declarations。变量声明总是可以显式地写成常规变量声明或命名函数参数;隐式短变量声明只是常规变量声明的简写。

    package main
    
    import (
        "fmt"
        "os"
    )
    
    func f() (err1 os.Error, err2 os.Error) {
        var fi *os.FileInfo
        fi, err1 = os.Stat("== err1 os.Error ==")
        _ = fi
        {
            var fi *os.FileInfo
            fi, err2 = os.Stat("== err2 os.Error ==")
            _ = fi
        }
        return
    }
    
    func main() {
        err1, err2 := f()
        fmt.Println("f() err1:", err1)
        fmt.Println("f() err2:", err2)
    }
    

    输出:

    f() err1: stat == err1 os.Error ==: no such file or directory
    f() err2: stat == err2 os.Error ==: no such file or directory
    

    在您的示例中,err 的短变量声明重新声明了err 的返回参数声明;他们在同一个街区。因此,新的err不会屏蔽返回参数err

    【讨论】:

    • 所以你的 2 个策略是:1)分配给一个临时的,然后从那里分配给不同范围的变量,2)把它吸起来,为那些不是的名称做“var”变量声明t 还存在,然后用“=”分配?我是否理解正确?
    • 这是两种策略。另外,有时您可以在内部块中使用带有变量列表的 return 语句,例如return n, err。从阅读各种主题和问题中可以看出,没有灵丹妙药。
    • 接受的答案略有错误:“因此,在简短的变量声明中,您不能重新声明最初在不同块中声明的变量。” - - 事实上,情况正好相反。检查这个:play.golang.org/p/NCTYWEU84z - x 在内部块中被明确地重新声明。在这种情况下使用:=var 没有区别,两者都有效:play.golang.org/p/SS8D1a4BsI ...我只是不确定它应该...
    【解决方案2】:

    无法绕过:= 声明的范围规则。只需明确使用var=

    【讨论】:

    • @MattJoiner 我在答案中添加了一个显式常规变量声明的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多