Currently:
func CopyFile(src, dst string) error {
r, err := os.Open(src)
if err != nil {
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
defer r.Close()
w, err := os.Create(dst)
if err != nil {
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
if _, err := io.Copy(w, r); err != nil {
w.Close()
os.Remove(dst)
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
if err := w.Close(); err != nil {
os.Remove(dst)
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
}
Proposal inspired by Java 7's try-with-resources:
func CopyFile(src, dst string) error {
check
r, err1 := os.Open(src); // Related to the first catch block
w, err2 := os.Create(dst); // Related to the second catch block, if the second catch block does not exists then the last existing catch block
_, err3 := io.Copy(w, r); // Related to the third catch block, if the third catch block does not exists then the last existing catch block
{
os.Remove(dst)
} catch _ {
return fmt.Errorf("copy %s %s: %v", src, dst, err1)
} catch _ {
// This catch block can be optional
return fmt.Errorf("copy %s %s: %v", src, dst, err2)
} catch _ {
// This catch block can be optional
return fmt.Errorf("copy %s %s: %v", src, dst, err3)
}
}
Error messages are the same format, simplified version:
func CopyFile(src, dst string) error {
check
r, err1 := os.Open(src);
w, err2 := os.Create(dst);
_, err3 := io.Copy(w, r);
{
os.Remove(dst)
} catch err { // Error pointer on err1, or err2, or err3
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
}
Notes:
- The
Open()
,Create()
, andCopy()
functions signature must befunction() T, error
where T is a generic type which implements aClose()
function. check
executes instructions one by one and implicitely does theerr != nil
operation, if err isn'tnil
, the relatedcatch
block is executed. Syntactic sugar: If the relatedcatch
block does not exists, try to execute the lastcatch
block.- You can add a "finally" block to this proposal.
- Drawback: This technique does not handle the last
if err := w.Close(); err != nil { ... }
block, but should a close method return an error? Even Java's or C#'s close function doesn't return anything :)