Golang中如何避免if/else外部无法访问变量及重复错误检查

Golang中如何避免if/else外部无法访问变量及重复错误检查 以下是我编写的一个程序块:

args := os.Args[1:]

if len(args) > 0 {
	csvFile, err := os.Open(args[1])
} else {
	csvFile, err := os.Open("problems.csv")
}

if err != nil {
	log.Fatal(err)
}

正如各位专家可能已经注意到的,csvFileerr 在 if/else 块外部是不可用的。但我也想避免在 if/else 块中每次都进行错误检查(假设有一个很长的 if/else 链)。

是否有 Go 语言的方式来实现我想要做的?


更多关于Golang中如何避免if/else外部无法访问变量及重复错误检查的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

我同意。另外,如果你要访问 args[1],请考虑 len(args) > 1 的情况。

更多关于Golang中如何避免if/else外部无法访问变量及重复错误检查的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我的建议:

args := os.Args[1:]
filename := "problems.csv"
if len(args) > 0 {
	filename = args[1]
}

csvFile, err := os.Open(filename)
if err != nil {
	log.Fatal(err)
}

鉴于您正在学习 Gophercises,我的解决方案更针对性地简化了参数解析部分:

filenamePtr := flag.String("file", "problems.csv", "a csv file with ques,ans")
flag.Parse()

csvFile, err := os.Open(*filenamePtr)
if err != nil {
	log.Fatal(err)
}

我的建议

args := os.Args[1:]
filename := "problems.csv"

if len(args) > 0 {
   filename = args[1]
}

csvFile, err := os.Open(filename)
if err != nil {
	log.Fatal(err)
}

为了简化我的编码,我尝试使用对象健身操 (https://williamdurand.fr/2013/06/03/object-calisthenics/)

在Go中处理这种情况的惯用方式是使用变量预声明和延迟赋值。以下是几种常见解决方案:

方案1:变量预声明 + 条件赋值

args := os.Args[1:]

var csvFile *os.File
var err error

if len(args) > 0 {
    csvFile, err = os.Open(args[0])  // 注意:应该是args[0]而不是args[1]
} else {
    csvFile, err = os.Open("problems.csv")
}

if err != nil {
    log.Fatal(err)
}

方案2:使用辅助函数减少重复

func openCSVFile(filename string) (*os.File, error) {
    if filename != "" {
        return os.Open(filename)
    }
    return os.Open("problems.csv")
}

func main() {
    args := os.Args[1:]
    
    var filename string
    if len(args) > 0 {
        filename = args[0]
    }
    
    csvFile, err := openCSVFile(filename)
    if err != nil {
        log.Fatal(err)
    }
    defer csvFile.Close()
}

方案3:使用默认值简化逻辑

args := os.Args[1:]

defaultFile := "problems.csv"
filename := defaultFile

if len(args) > 0 {
    filename = args[0]
}

csvFile, err := os.Open(filename)
if err != nil {
    log.Fatal(err)
}
defer csvFile.Close()

方案4:处理更复杂的if/else链

func getDataSource(args []string) (io.ReadCloser, error) {
    switch {
    case len(args) == 0:
        return os.Open("problems.csv")
    case args[0] == "-":  // 从标准输入读取
        return os.Stdin, nil
    case strings.HasPrefix(args[0], "http://"), strings.HasPrefix(args[0], "https://"):
        resp, err := http.Get(args[0])
        if err != nil {
            return nil, err
        }
        return resp.Body, nil
    default:
        return os.Open(args[0])
    }
}

func main() {
    source, err := getDataSource(os.Args[1:])
    if err != nil {
        log.Fatal(err)
    }
    defer source.Close()
}

第一种方案是最直接的修复,通过预先声明变量,然后在if/else块中赋值,这样变量在外部作用域就可用,同时避免了重复的错误检查。

回到顶部