我有这段代码,我不喜欢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
}
这一次在此代码中再次出现了与上面相同的某些情况:
答案 0 :(得分:0)
在标准库中可以看到很多是特定的函数,这些函数包装了更多的通用非导出函数。请参阅下面的注释代码。
// download is a rather generic function
// and probably you can refactor downloadTemporaryFile
// so that even this function is not needed any more.
func (r *RedditVideo) download(prefix, url string) (filename string, error error) {
outputFile, err := downloadTemporaryFile(
r.VideoURL,
prefix,
)
if err == nil {
return "", fmt.Errorf("Error while download: %s", err)
}
return outputFile.Name(), nil
}
// DownloadVideo wraps download, handing over the values specific
// to the video download
func (r *RedditVideo) DownloadVideo() (filename string, averror error) {
return r.download(TemporaryVideoFilePrefix, r.VideoURL)
}
// DownloadAudio wraps download, handing over the values specific
// to the audio download
func (r *RedditVideo) DownloadAudio() (filename string, averror error) {
return r.download(TemporaryAudioFilePrefix, r.AudioURL)
}
func main() {
r := RedditVideo{
VideoURL: os.Args[1],
AudioURL: os.Args[2],
}
var videoerror, audioerror error
var videofileName, audiofileName string
if videofileName, videoerror = r.DownloadVideo(); videoerror != nil {
fmt.Println("Got an error downloading the video")
}
if audiofileName, audioerror = r.DownloadAudio(); audioerror != nil {
fmt.Println("Got an error downloading the audio")
}
fmt.Printf("Video:\t%s\nAudio:\t%s", videofileName, audiofileName)
}
通过这种方式,很明显,返回的错误源于哪个下载。
答案 1 :(得分:0)
来自https://blog.golang.org/error-handling-and-go:
Go代码使用错误值指示异常状态。
根据您的情况,音频是可选的,视频是必需的。因此,只有视频下载应返回错误:
// Download will download the audio and video files to a particular path
// empty outputAudioFileName indicates inability to download Audio File
func (r *RedditVideo) Download() (outputVideoFileName string, outputAudioFileName string, err error) {
outputVideoFile, err := downloadTemporaryFile(
r.VideoURL,
TemporaryVideoFilePrefix,
)
if err != nil {
return "", "", err
}
outputVideoFileName := outputVideoFile.Name()
outputAudioFile, errAudio := downloadTemporaryFile(
r.AudioURL,
TemporaryAudioFilePrefix,
)
outputAudioFileName := ""
if errAudio == nil {
outputAudioFileName = outputAudioFile.Name()
} else {
// Log error, it is still important to fix it
}
return outputVideoFileName, outputAudioFileName, nil
}
经验法则-任何可能产生异常状态的代码都应在下一行:
if err != nil {
return funcResult, err
}