我正在尝试编写一个用于Rails项目国际化的YAML字典。我有点困惑,因为在一些文件中,我看到双引号中的字符串,而有些没有。需要考虑几点:
!
- 非特定标记,而第一个示例的最后两行不使用 - 它们都有效。 我的问题是:在YAML中使用不同类型的引号有哪些规则?
可以这么说:
!
单引号,当......?!?答案 0 :(得分:441)
在对问题中引用的YAML食谱和一些测试进行简要回顾之后,这是我的解释:
10
,但您希望它返回字符串而不是Fixnum,请写'10'
或"10"
。:
,{
,}
,[
,]
,,
, &
,*
,#
,?
,|
,-
,<
,>
,{{ 1}},=
,!
,%
,@
)。\
将作为字符串'\n'
返回。\n
将作为换行符返回。"\n"
返回Ruby符号。对我来说,最好的方法是不使用引号,除非你必须,然后使用单引号,除非你特别想要处理转义码。
更新
“是”和“否”应用引号(单引号或双引号)括起来,否则它们将被解释为TrueClass和FalseClass值:
!ruby/sym
答案 1 :(得分:4)
标记为正确的答案具有极大的误导性。 (虽然解释了野外遇到的yaml)
yaml 中的字符串仅在 (的开头)值可能被误解为数据类型 或值包含“:”(因为它可能被误解为键)时才需要引用。< /p>
例如
foo: '{{ bar }}'
需要引号,因为它可能会被误解为数据类型 dict
,但是
foo: barbaz{{ bam }}
不会,因为它不以关键字符开头。接下来,
foo: '123'
需要引号,因为它可能会被误解为数据类型 int
,但是
foo: bar1baz234
bar: 123baz
不会,因为它不能被误解为 int
foo: 'yes'
需要引号,因为它可能会被误解为数据类型 bool
foo: "bar:baz:bam"
需要引号,因为值可能会被误解为键。
这些只是示例。使用 yamllint
有助于避免使用错误的标记开始值
foo@bar:/tmp$ yamllint test.yaml
test.yaml
3:4 error syntax error: found character '@' that cannot start any token (syntax)
如果使用 yaml 高效工作,这是必须的。
如某些人所建议的那样引用所有字符串,就像在 python 中使用括号一样。这是一种不好的做法,会损害可读性并抛弃不必引用字符串的美丽特性。在传播虚假知识之前,请阅读文档。
答案 2 :(得分:4)
虽然 Mark 的回答很好地总结了根据 YAML 语言规则何时需要引号,但我认为许多开发人员/管理员在使用 YAML 中的字符串时会问自己“什么应该成为我的处理刺痛的经验法则吗?”
这听起来可能很主观,但是如果您想仅在真正根据语言规范需要时使用引号,那么您必须记住的规则数量, 对于指定最常见的数据类型之一这样简单的事情来说有点过分。不要误会我的意思,您最终会在定期使用 YAML 时记住它们,但是如果您偶尔使用它,并且您没有开发编写 YAML 的自动化呢?您真的想花时间记住所有规则只是为了正确指定字符串吗?
“经验法则”的全部意义在于节省认知资源并在不假思索的情况下处理常见任务。我们的“CPU”时间可以说比正确处理字符串更有用。
从这个纯粹实用的角度来看,我认为最好的经验法则是单引号字符串。背后的原因:
这只是一些偶尔使用 YAML 的用户需要记住的 2 条规则,从而最大限度地减少认知工作。
答案 3 :(得分:1)
在使用 Docker 的 Rails 应用程序时,我有这个担忧。
我最喜欢的方法是通常不使用引号。这包括不使用引号:
${RAILS_ENV}
之类的变量postgres-log:/var/log/postgresql
但是,我对integer
值使用双引号,这些值需要转换为以下字符串:
version: "3.8"
"8080:8080"
但是,对于booleans
,floats
,integers
之类的特殊情况,以及在其他情况下使用双引号作为输入值的情况,可以解释为strings
,请不使用双引号。
这里有一个示例docker-compose.yml
文件来解释这个概念:
version: "3"
services:
traefik:
image: traefik:v2.2.1
command:
- --api.insecure=true # Don't do that in production
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
仅此而已。
我希望这会有所帮助