为什么 YAML 规范在冒号后强制要求 space?

Why does the YAML spec mandate a space after the colon?

YAML spec 明确指出:

Mappings use a colon and space (“: ”) to mark each key: value pair.

所以这是合法的:

foo: bar

但这不是:

foo:bar

我看到网上很多人都在抱怨 space。我认为他们说得有道理。我自己也被它烫过好几次。

为什么 space 是强制性的?它背后的设计考虑是什么?

很容易错过,因为该规范使用了仅突出显示内部 link 的最后一个字符的奇怪约定,但您引用的部分中的 “: ” 实际上是 link to another section of the specification 回答了你的问题:

Normally, YAML insists the “:” mapping value indicator be separated from the value by white space. A benefit of this restriction is that the “:” character can be used inside plain scalars, as long as it is not followed by white space. This allows for unquoted URLs and timestamps. It is also a potential source for confusion as “a:1” is a plain scalar and not a key: value pair.

所以动机是您可以编写这样的列表而不需要任何引用:

useful_values:
- 2:30
- http://example.com
- localhost:8080

如果 space 是可选的,这最终可能会变得模棱两可,并被解释为一组 key-value 对。

旁白:这里有一段 JS 可以使该文档上的 link 格式不再那么无用。

document.styleSheets[0].insertRule('a[href^="#"] { color: #00A !important; text-decoration: underline !important; background: none !important; }', 0);

实际上,列后的 space 并非 总是 强制。如果满足两个条件则可选:

    使用
  1. Flow 样式 语法(又名 JSON / one-liner / {} / []);
  2. 引用了密钥。

此语法有效(pyyaml=5.3.1):

{"x":abc}

输出:{'x': 'abc'}

但要小心:

{x:abc}  # {'x:abc': None}
  # Can't separate key from value if not quoted
---
{x:"abc"}  # {'x:"abc"': None}
  # Same problem

更多带有冒号和 space 的极端情况:

x:::abc  # 'x:::abc'
    # Scalar, not a key-value
---
x:: :abc  # {'x:': ':abc'}
    # Avoid this, use quotes to be safe if `:` is
    # involved in either key or value.
---
{x:: :abc}  # Error: while parsing a flow node expected the node
            # content, but found ':'
    # Parsing logic for flow syntax can be surprising.
---
{"x:":":abc"}  # {'x:': ':abc'}
    # Follow the "least surprise principle" - stick to JSON syntax.