【问题标题】:Golang command arguments empty causing errorGolang 命令参数为空导致错误
【发布时间】:2015-07-29 21:18:15
【问题描述】:

我正在编写一个 go 程序,我需要使用命令参数。但是,如果我在运行可执行文件或go run gosite.go 代码时不传递参数,则会出现以下运行时错误。

panic: runtime error: index out of range

goroutine 1 [running]:
runtime.panic(0x80c8540, 0x816d4b7)
/usr/lib/go/src/pkg/runtime/panic.c:266 +0xac
main.main()
/home/jacob/github/gosite/src/github.com/zachdyer/gosite/gosite.go:11 +0x168

在第 11 行发现错误。所以我的问题是我是否以错误的方式使用 os.Args?这需要以不同的方式初始化吗?另外为什么它似乎在那里无限循环?如果我传入一个参数,程序运行时不会出现任何错误并打印该参数。

import (
    "fmt"
    "os"
)

var root string

func main() {
    command := os.Args[1]
    if command != "" {
        fmt.Println(command)
    } else {
        command = ""
        fmt.Println("No command given")
    }

    createDir("public")
    createDir("themes")
}

func createDir(dir string) {
    root = "../../../../"
    err := os.Mkdir(root + dir, 0777)
    if err != nil {
        fmt.Println(err)
    }

}

【问题讨论】:

    标签: go command-line-arguments


    【解决方案1】:

    首先检查os.Args slice 的长度,并且只索引到它的长度 - 1:

    if len(os.Args) > 1 {
        command := os.Args[1]
        // do something with command
    } else {
        // No arguments were specified!
    }
    

    os.Args 保存命令行参数,以程序名称开头。

    os.Args[0] 是程序名称。 如果有论据,就去Args[1],Args[2]...

    如果没有指定参数,os.Args 的长度将为 1,并且只包含程序名称。

    还可以查看flag 包,以便更轻松、更复杂地处理参数。

    【讨论】:

      【解决方案2】:

      您必须先检查 os.Args 是否存在以及它有多大,然后才能访问它。这在每一种使用数组的编程语言中都是最实用的。

      这应该可行:

      func main() {
      
          if (os.Args != nil && len(os.Args) > 1) {
              command := os.Args[1]
              if command != "" {
                  fmt.Println(command)
              } else {
                  command = ""
                  fmt.Println("No command given")
              }
          }
          createDir("public")
          createDir("themes")
      }
      

      取决于所有只能去的故障查找器,并且已经阅读了这里的手册,正确的唯一去处理输入参数的特定版本。 (我之前很伤心的一个注释,我不开发 go,我通过处理数组的最佳实践来回答,以防止超出范围错误):

      func main() {
      
          if (len(os.Args) > 1) {
              command := os.Args[1]
              if command != "" {
                  fmt.Println(command)
              } else {
                  command = ""
                  fmt.Println("No command given")
              }
          }
          createDir("public")
          createDir("themes")
      }
      
      1. 它不再检查 nil,因为 os.Args 总是被初始化并在索引 0 上保存应用程序名称
      2. 它检查大于 1 的 len 以确保索引 1 存在。或者换句话说,用户输入了参数并且 os.Args 有更多的条目,然后只有应用名称。

      【讨论】:

      • os.Args 以程序名称开头,所以你应该检查len() > 1。也不需要测试它是否是nil(冗余),内置的len()函数也适用于nil切片。
      • 我没有开发 go ;) 正如我所说,我的解决方案是每个来源未知的数组的最佳实践。因此,当您想保持清洁和正确时,请像我一样做,而忽略为您处理此问题;)
      • 我不认为这是一个很好的建议,基本上你是在说“忘记你用哪种语言编码,只使用所有语言的公共子集”。这样做你最终会得到不必要的复杂、丑陋和非惯用的代码。此外,len() > 1 检查是强制性的,仅检查 len() > 0 如果未指定参数,您可能会遇到相同的错误,因为 len() > 1 始终为真,因为 Args 包含程序名称,但如果未指定参数, Args[1] 将导致:runtime error: index out of range
      • 正如你所说 ;) 继续前进,我继续应用计算机科学:D
      • 这仍然会像问题一样恐慌。 len(os.Args) > 0 始终为真,并且不检查任何命令行参数。
      猜你喜欢
      • 2019-06-25
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      相关资源
      最近更新 更多