Which of the 2 solutions is written better? Personally I prefer the one line method but it does make it slightly more difficult to debug. Is perhaps doing it the long way first then refactoring to the second method once we know all is tested to be working.
Please note Environment var "FT_SOURCE" is set to "c:\filemover\"
Original solution...
func ensureDirold(dirName string) (string, error) {
err := os.Mkdir(dirName, os.ModeDir)
if err == nil || os.IsExist(err) {
return dirName, nil
} else {
return dirName, err
}
}
Usage...
func OldWay() {
dir := os.Getenv("FT_SOURCE") //is set to c:\filemover
fmt.Print(ensureDirold(dir))
_, err := os.Create(dir + "myfile-old.txt")
check(err)
}
Alternate Solution...
type strerr struct {
str string
err error
}
func ensureDirnew(dirName string) strerr {
err := os.Mkdir(dirName, os.ModeDir)
if err == nil || os.IsExist(err) {
return strerr{
str: dirName,
err: nil,
}
} else {
return strerr{
str: dirName,
err: err,
}
}
}
Usage...
func NewWay() {
_, err := os.Create(ensureDirnew(os.Getenv("FT_SOURCE")).str + "myfile.txt")
check(err)
}
1 Answer 1
Create a directory if it doesn't exist.
Don't report an error if the directory exists.
Isn't that a simple wrapper for the Go standard library os.Mkdir
function?
For example,
// mkdir, like os.Mkdir, creates a new directory
// with the specified name and permission bits.
// If the directory exists, mkdir returns nil.
func mkdir(name string, perm os.FileMode) error {
err := os.Mkdir(name, perm)
if err != nil {
if !os.IsExist(err) {
return err
}
}
return nil
}
Personally I prefer the one line method.
In Go, we favor readability and simplicity for correct and maintainable code. Use the Go idiom for creating a file:
f, err := Create(fileName)
if err != nil {
// handle error
}
defer f.Close()
For your usage, use a wrapper for the Go standard library os.Create
function.
For example,
// createFT, like os.Create, creates the named file with mode 0666 (before umask),
// truncating it if it already exists.
// The file is created in the directory named in the FT_SOURCE environment variable.
func createFT(fileName string) (*os.File, error) {
dirKey := "FT_SOURCE"
dirName, ok := os.LookupEnv(dirKey)
if !ok {
err := fmt.Errorf("%s environmemt variable not found", dirKey)
return nil, err
}
perm := os.FileMode(0666)
err := mkdir(dirName, perm)
if err != nil {
return nil, err
}
f, err := os.Create(filepath.Join(dirName, fileName))
if err != nil {
return nil, err
}
return f, nil
}
Functions are used to encapsulate implementation details. Functions can also be used to hide complexity and "ugly" code.
Explore related questions
See similar questions with these tags.
dir + "myfile-old.txt"
it should befilepath.Join(dir, "myfile-old.txt")
. \$\endgroup\$ensureDir
returns it's argument. It's asking a boolean yes/no question (that can possibly fail). Your "alternate" doesn't seem at all idiomatic to me and you appear to completely ignore any error fromensureDirnew
. \$\endgroup\$