I have following code:
func main() {
// counts := make(map[string]int)
files := os.Args[1:]
if len(files) == 0 {
counts := make(map[string]int)
countLines(os.Stdin, counts)
fmt.Println("os.Stdin")
printCounts(counts)
} else {
for _, arg := range files {
counts := make(map[string]int)
f, err := os.Open(arg)
if err != nil {
fmt.Fprintf(os.Stderr, "dup2: %v
", err)
continue
}
countLines(f, counts)
f.Close()
// print counts of each file
printCounts(counts)
}
}
}
func printCounts(counts map[string]int) {
//...
}
func countLines(f *os.File, counts map[string]int){
//...
}
where i repeat myself in if-else statement by initiating counts dict twice, (counts := make(map[string]int)
) both in if and else.
My question is what is the gopher-way of writing this?
Is that better to do the allocation outside the if-else statment with new
and do initiation in every block?
I don't see much repetition in your code. You could somehow merge both if and else part but I'm not a fan of.
A simple refactor is moving counts
initialization into your countLines
function and make it return it.
func countLines(f *os.File, counts map[string]int)
->
func countLines(f *os.File) map[string]int
And don't think much about allocations until you are doing a lot (let's say at least 100K allocations) and profile your code before doing little optimizations. Maps will allocate memory not only on make
but also when you append to them and their hash table is full.