1

I have the following code:

if entryJson, err := json.MarshalIndent(entry, "", " "); err != nil{
    log.Println(err)
} else {
    log.Println(entryJson)
}

if err := ioutil.WriteFile("text.json", entryJson, 0644); err != nil {
    log.Println(err)
}

I want to limit the scope of err as much as possible. The problem I'm facing with this is, that the variable entryJson is out of scope when I want to write it to the file.
What is the idiomatic way to deal with this. Should I just reuse the variable err and check for it in an additional if block? Like this:

entryJson, err := json.MarshalIndent(entry, "", " ")
if err != nil{
    log.Println(err)
} else {
    log.Println(entryJson)
}

err = ioutil.WriteFile("text.json", entryJson, 0644)
if err != nil{
    log.Println(err)
}

This works but looks less readable to me.

Chris
  • 515
  • 2
  • 6
  • 13
  • 1. why do you want to limit it? what's your logic there. 2. both `if err = ioutil.WriteFile("text.json", entryJson, 0644); err != nil{}` and `if err := ioutil.WriteFile("text.json", entryJson, 0644); err != nil{}` works fine – OneOfOne Apr 10 '16 at 15:44
  • I have no particular reason limiting the scope. It just seemed a good idea and was encouraged by the course I took. (I'm fairly new to Go coming from a Java background.) – Chris Apr 10 '16 at 16:20

2 Answers2

2

First, there's no need to isolate variables. Second, you can do short-hand assignment inside if statements, for example:

entryJson, err := json.MarshalIndent(entry, "", " ")
if err != nil{
    log.Println(err)
} else {
    log.Println(entryJson)
}

if err = ioutil.WriteFile("text.json", entryJson, 0644); err != nil{
    log.Println(err)
}

// or if you want to limit the scope of err badly, this is also legal:

if err := ioutil.WriteFile("text.json", entryJson, 0644); err != nil{
    log.Println(err)
}

A clean way to handle this specific example though is to put it in it is own function and call it:

func writeJSON(fn string, v interface{}) error {
    j, err := json.MarshalIndent(v, "", " ")
    if err != nil {
        return err
    }

    return ioutil.WriteFile(fn, j, 0644)
}

func main() {
    var test struct {
        A string
        B string
    }
    if err := writeJSON("file.json", test); err != nil {
        log.Fatal(err)
    }
}
OneOfOne
  • 95,033
  • 20
  • 184
  • 185
  • 2
    From what I understand of Go, which is admittedly not that much yet, I find the second solution of this answer to be the best. In my specific example this is particular true since I have now another methods which will use the same logic to write to the JSON. Therefore putting it into a separate function makes the most sense and limits the scope. Thank you. – Chris Apr 11 '16 at 09:25
  • @Chris welcome to Go, the #1 tip I can give you is, don't try to apply other languages to Go, once you can do that, your experience with Go will be much better. – OneOfOne Apr 11 '16 at 14:54
0

You can write file in the else statement following the error checking, although I can't say it's idiomatic/readable.

var entry = []byte(`{
    "name": "bob",
    "age" : 74
}`)

func main() {
    if entryJson, err := json.MarshalIndent(entry, "", " "); err != nil {
        log.Fatal(err)
    } else {
        if err = ioutil.WriteFile("text.json", entryJson, 0644); err != nil {
            log.Fatal(err)
        }   
    }
}
Pandemonium
  • 7,724
  • 3
  • 32
  • 51