【发布时间】:2018-12-19 20:21:13
【问题描述】:
我有这段代码,我不喜欢这种感觉,更不用说golint 不喜欢error should be the last type when returning multiple items (golint)。解释这段代码:
- 我想让用户决定他们是否关心返回的任何错误
- 特别是在此代码中,有时不需要或不需要音频文件,可以忽略它
- 无论用户在做什么,都可能总是需要视频和输出文件
我愿意以任何方式重构它(无论是将其拆分、移动等)。Go 中有没有更惯用的方式来完成这样的事情?
// Download will download the audio and video files to a particular path
func (r *RedditVideo) Download() (outputVideoFileName string, outputAudioFileName string, errVideo error, errAudio error) {
outputVideoFile, errVideo := downloadTemporaryFile(
r.VideoURL,
TemporaryVideoFilePrefix,
)
if errVideo == nil {
outputVideoFileName = outputVideoFile.Name()
}
outputAudioFile, errAudio := downloadTemporaryFile(
r.AudioURL,
TemporaryAudioFilePrefix,
)
if errAudio == nil {
outputAudioFileName = outputAudioFile.Name()
}
return outputVideoFileName, outputAudioFileName, errVideo, errAudio
}
同样,我发现自己后来在代码中再次使用了同样的模式:
// SetFiles sets up all of the input files and the output file
func (l *localVideo) SetFiles(inputVideoFilePath string, inputAudioFilePath string, outputVideoFilePath string) (errVideo error, errAudio error, errOutputVideo error) {
// Set input video file
l.inputVideoFile, errVideo = os.Open(inputVideoFilePath)
if errVideo != nil {
return
}
if errVideo = l.inputVideoFile.Close(); errVideo != nil {
return
}
// Set output video file
l.outputVideoFile, errOutputVideo = os.Create(outputVideoFilePath)
if errOutputVideo != nil {
return
}
if errOutputVideo = l.outputVideoFile.Close(); errOutputVideo != nil {
return
}
// IMPORTANT! Set input audio file LAST incase it is nil
l.inputAudioFile, errAudio = os.Open(inputAudioFilePath)
if errAudio != nil {
return
}
if errAudio = l.inputAudioFile.Close(); errVideo != nil {
return
}
return
}
这次在这段代码中再次出现了一些与上面相同的情况:
- 我们关心视频和输出的设置,可能关心也可能不关心音频
- 有多个错误需要由用户处理
【问题讨论】:
-
返回一个音频文件和一个视频文件和一个音频错误和一个视频错误非常非常强烈地表明这个函数做的太多了,应该是两个函数。
-
特别注意“有时不需要或不需要音频文件,它可以被忽略”我会说这只需要重构为两个函数,每个函数做一件事而不是一个函数做两件事。
-
我会尝试输入错误,或者只创建
DownloadVideo和DownloadAudio -
这实际上意味着我们两次下载文件,检查我们是否可以两次打开它并两次都返回错误。在我看来,它可以重构为单一方法。
-
有了额外的代码,这绝对是需要进行一些严重重构的情况。函数应该做一件事并且把它做好。这不仅在 Go 中是惯用的,而且在任何语言中都是普遍的良好做法。
标签: go error-handling