This question already has an answer here:
I have some strings that I'd like to convert to JSON. Using encoding/json here, haven't tried other packages.
The strings may contain newlines and other stuff that breaks JSON if saved as-is.
It works if I pass a string literal - it adds backslashes in front of backslashes. It doesn't work if I just pass a regular string. I can't seem to figure out if there is a way to use variables that contain string literals.
edit: as pointed out, these are not the same values and I kind of understand that, but it doesn't help me solve my problem.
The sample code:
package main
import (
"fmt"
"encoding/json"
)
func main() {
type Test struct {
Input string
}
regularString := Test{"asd
qwe"}
out, err := json.Marshal(regularString)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(out))
literalString := Test{`asd
qwe`}
out, err = json.Marshal(literalString )
if err != nil {
fmt.Println(err)
}
fmt.Println(string(out))
}
</div>
The encoding/json
properly encodes all string values.
Your first example works as you expect it because you use an interpreted string literal, and if that contains a sequence, the compiler will replace that with a newline character.
Your second example doesn't work as you expect it because you used a raw string literal, which if contains a sequence, that will not be replaced, but those 2 characters will remain in the string. And that will be escaped by
encoding/json
properly to remain that in the JSON outpupt.
So basically
"asd
qwe"`
and
`asd
qwe`
are 2 different strings, they are not equal, hence their JSON escaped values are also different.
Check Spec: String literals for more details.
Note that if you want to create a string value using a raw string literal, you can't use escape sequences in it. To have a newline in a raw string literal, simply break the line, like this:
s := `asd
qwe`
Another option is to "break" the string literal, and insert the newline using an interpreted string literal (and concatenate the parts):
s := `asd` + "
" + `qwe`