HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoMinor

cat program in Go

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
programcatstackoverflow

Problem

In order to learn Go, I've implemented the cat program in Go. I want to know if the code is idiomatic and what could be improved.

package main

import "fmt"
import "io"
import "os"

var errors int

func main() {
    catFilesOrStdin(os.Args[1:])
    os.Exit(getExitValue())
}

func getExitValue() int {
    if (hadErrors()) {
        return 1
    } else {
        return 0
    }
}

func hadErrors() bool {
    return errors > 0
}

func catFilesOrStdin(files []string) {
    if len(files) > 0 {
        catFiles(files)
    } else {
        catStream(os.Stdin)
    }
}

func catFiles(files []string) {
    for _,file := range files {
        catFile(file)
    }
}

func catFile(file string) {
    stream, err := os.Open(file)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        errors++
        return
    }
    catStream(stream)
    defer stream.Close()
}

func catStream(stream *os.File) {
    _, err := io.Copy(os.Stdout, stream)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        errors++
    }
}

Solution

I'd put the defer statement in catFile above the call to catStream, not after.

You might want to consider log.Fatal if the os.Open fails.

If you're importing multiple packages, the standard is a single import statement with all the packages in parentheses.

The global errors variable technically should be protected with a sync.Mutex, but more importantly, log.Fatal on any error instead.

Context

StackExchange Code Review Q#100727, answer score: 4

Revisions (0)

No revisions yet.