首页 > 解决方案 > 我怎样才能不在go中重新分配变量?

问题描述

我不明白如何在 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

解决方案


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

首先创建预期的第二个变量,并使用简单的赋值而不是短变量声明

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上尝试。

查看相关问题:

为什么在golang中只初始化定义中的一个变量会失败

为什么 Go 中有两种声明变量的方式,有什么区别,用哪一种?


推荐阅读