Inconsistent behaviour when marshalling strings
eBerdnA opened this issue · comments
I have the following input file.
title: "2023-08-23"
title2: "A title with a colon: inside"
title3: '2023-08-23'
Using the following code I get a slightly unexpected result. I use v3.0.1
and go1.20.2 darwin/arm64
for this.
rawYaml, _ := os.ReadFile("./input.yaml")
yamlMap := make(map[string]string)
yaml.Unmarshal(rawYaml, &yamlMap)
marschalled, _ := yaml.Marshal(yamlMap)
fmt.Println(string(marschalled))
The output is the following.
title: "2023-08-23"
title2: 'A title with a colon: inside'
title3: "2023-08-23"
My questions is, why is title
still encapsulated in double quotes but title2
is only encapsulated with single quotes and title3
even gets switched over. For me this behaviour looks quite confusing and inconsistent.
In YAML, both single and double quotes denote strings. However, they have slightly different behaviors:
- Double Quotes (""): Within double quotes, you can include special escape sequences similar to those in C and Javascript, such as \n (newline), \t (tab), etc.
- Single Quotes (''): Strings within single quotes are literal string notations. There are no escape sequences. If you want to include a single quote within a single-quoted string, you have to use two consecutive single quotes, i.e., ''.
Regarding the behavior you're seeing, this discrepancy is due to how the gopkg.in/yaml.v3 package handles strings when marshalling YAML in Go. The YAML package outputs a valid YAML representation of a string, choosing the appropriate style (plain, single-quoted, or double-quoted) given the content of the string.
Here's a bit more specifics:
- title: "2023-08-23": The value is formatted somewhat like a date or a number and might therefore be interpreted as such by some parsers. To prevent this misinterpretation, the library encapsulates it in quotes. The YAML spec mandates that unquoted representations of dates/times and numbers be converted into their native types.
- title2: 'A title with a colon: inside': The colon (:) in YAML acts as a key-value separator. When a colon is present in the string, the yaml.v3 package uses single quotes to avoid treating it as a key-value separator. Note that the package could also have used double quotes, but it chose single quotes.
- title3: '2023-08-23': You have quoted this as a single-quoted string in your input, but the yaml.v3 package converts it to a double-quoted string in the output for the reasons explained above.
Both, single-quoted and double-quoted representations are valid YAML and equivalent in value.