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)
}
正如各位专家可能已经注意到的,csvFile 和 err 在 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块中赋值,这样变量在外部作用域就可用,同时避免了重复的错误检查。

