【问题标题】:How can I not reassign a variable in go? [duplicate]我怎样才能不在go中重新分配变量? [复制]
【发布时间】:2021-01-19 19:25:31
【问题描述】:

我不明白如何在 go 中适当地重新分配块范围内的变量。

package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    base := "/a/b/c"
    other := "/a/b/c/d/e"

    for base != other {
        other, file := filepath.Split(other) // "other declared but not used"
        fmt.Println(file)
    }
}

我想使用filepath.Split 的两个部分,所以我需要:=,因为file 尚未声明。我想让other越来越短,所以我重新分配了filepath.Split的结果,但是go编译器不允许我运行这段代码。

为什么会这样,我该怎么做?

【问题讨论】:

    标签: go


    【解决方案1】:

    循环的主体是另一个块,因此在其中使用短变量声明将不会使用之前在循环之外声明的other 变量,而是会创建一个新的other 变量,范围为主体块.鉴于此,第二个other 变量不会在任何地方使用,因为循环中的base != other 条件引用外部other 变量,因此会出现编译时错误。

    首先创建预期的第二个变量,并使用简单的assignment 而不是short variable declaration

    base := "/a/b/c"
    other := "/a/b/c/d/e"
    
    for base != other {
        var file string
        other, file = filepath.Split(other) // "other declared but not used"
        fmt.Println(file)
    }
    

    注意上面的代码会陷入死循环,因为filepath.Split()other中留下了斜杠,所以在下一次迭代中filepath.Split()将返回相同的other(最后一个目录不会被剪切关闭),并且永远不会再改变。

    要让你的代码做你想做的事,你必须剪掉尾部的斜线,像这样:

    for base != other {
        var file string
        other, file = filepath.Split(other) // "other declared but not used"
        fmt.Println(file)
        if strings.HasSuffix(other, "/") {
            other = other[:len(other)-1]
        }
    }
    

    现在将运行并输出(在Go Playground 上尝试):

    e
    d
    

    请注意,如果您使用filepath.Base() 获取路径的最后一部分,并使用filepath.Dir() 获取父文件夹,则可以使用更简单的代码来实现相同的目标,如下所示:

    base := "/a/b/c"
    other := "/a/b/c/d/e"
    
    for base != other {
        fmt.Println(filepath.Base(other))
        other = filepath.Dir(other)
    }
    

    这个输出一样,在Go Playground上试试。

    查看相关问题:

    Why does initializing just one variable in a definition fail, in golang

    Why there are two ways of declaring variables in Go, what's the difference and which to use?

    【讨论】:

    • 这行得通,谢谢。但是为什么我不能在这里使用短变量声明呢?
    • @samuelstevens 添加了更多解释、修复了代码并展示了一个更简单的替代方案。
    • "循环体是另一个块,因此在其中使用短变量声明不会使用之前在循环之外声明的另一个变量,而是会创建一个新的其他变量,范围为“这是有道理的。它是否记录在某个地方,或者只是我应该知道的 Go 的一部分?
    • 是的,它已记录在案:Spec: Short variable declaration:“与常规变量声明不同,短变量声明可能会重新声明变量,前提是它们最初是在同一块中声明的(或者参数列表,如果block 是函数体)具有相同的类型,并且至少有一个非空白变量是新的。因此,重新声明只能出现在多变量短声明中。重新声明不引入新变量;它只是为原始值分配一个新值。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 2022-01-04
    • 2022-01-24
    • 2022-11-21
    • 2018-07-09
    相关资源
    最近更新 更多