如何正确使用“for..in” Coffeescript 对象缩进内的列表理解?
我刚刚开始使用 Coffeescript,所以我可能会问一些非常微不足道的问题,但这个“错误”最近让我绊倒:
class Foo
toJSON_1: ->
title: 'toJSON_1'
items: i for i in [1..5]
toJSON_2: ->
items: i for i in [1..5]
title: 'toJSON_2'
toJSON_3: ->
items: (i for i in [1..5])
title: 'toJSON_3'
foo = new Foo
console.log(foo.toJSON_1())
console.log(foo.toJSON_2())
console.log(foo.toJSON_3())
我会考虑所有这些等效项,但看看 JSON_2
会发生什么:
{ title: 'toJSON_1', items: [ 1, 2, 3, 4, 5 ] }
{ title: 'toJSON_2' }
{ items: [ 1, 2, 3, 4, 5 ], title: 'toJSON_3' }
调试花了一些时间,因为我正在遵循使用符号 JSON_1
的教程,但在我的代码中,列表理解不是最后一项(即 JSON_2
) ,直到我偶然发现了测试 JSON_3
。
有人可以向我解释为什么 CoffeeScript 解析器以这种方式工作吗?一般情况下正确的习语是什么?我应该始终将列表推导式括在括号内吗?听起来像是一个等待发生的错误,总是假设只有一个列表理解,并且它将位于对象声明的末尾。
也许这只是我不知道的解析器规则的特殊情况......?
编辑:
进一步使用编译器并生成 Javascript,看起来将代码封装在 {}
括号中,让 Coffeescript 做正确的事情 /em>:
toJSON_2: ->
{
items: i for i in [1..5]
title: 'toJSON_2
}
我想我的问题可以归结为:
- 使用
{}
括号或括号更惯用吗 围绕列表理解? - 这种“不可预测”的行为是一个错误吗?
- 如果没有,为什么不呢?
I'm just getting started with Coffeescript, so I may be asking something really trivial, but this "bug" recently tripped me up:
class Foo
toJSON_1: ->
title: 'toJSON_1'
items: i for i in [1..5]
toJSON_2: ->
items: i for i in [1..5]
title: 'toJSON_2'
toJSON_3: ->
items: (i for i in [1..5])
title: 'toJSON_3'
foo = new Foo
console.log(foo.toJSON_1())
console.log(foo.toJSON_2())
console.log(foo.toJSON_3())
I would have considered all of these equivelant, but look what happens with JSON_2
:
{ title: 'toJSON_1', items: [ 1, 2, 3, 4, 5 ] }
{ title: 'toJSON_2' }
{ items: [ 1, 2, 3, 4, 5 ], title: 'toJSON_3' }
It took a while to debug, because I was following along with a tutorial using notation JSON_1
, but in my code the list comprehension was not the last item (i.e. JSON_2
), until I stumbled upon testing JSON_3
.
Can someone explain to me why the CoffeeScript parser works with this way? And what is the proper idiom in the general case? Should I always wrap list comprehensions inside parens? Sounds like a bug waiting to happen to always assume there will only be one list comprehension and it will be at the end of the object declaration.
Maybe this is just a peculiar situation of a parser rule I'm not aware of...?
EDIT:
Playing with the compiler and generated Javascript some more, it looks like it's enough to wrap the code in {}
brackets for Coffeescript to do the right thing:
toJSON_2: ->
{
items: i for i in [1..5]
title: 'toJSON_2
}
I guess my question boils down to:
- is it more idiomatic to use the
{}
brackets or put parentheses
around the list comprehensions? - is this "unpredictable" behavior a bug?
- if not, why not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
建议在构建数组时将推导式括在括号中,因为
items = (item for item in list when x is y)
。在 toJSON_2 中,第一行被解释为
您不能为此责怪咖啡脚本,因为意图尚不清楚。我的建议是遵循一个简单的准则:任何会使人类感到困惑的东西很可能会让解析器感到困惑。
这包括将表达式括在括号中、使用显式返回值、对象文字括号、临时变量以及在代码中明确表达意图所需的任何内容。
It's recommended to wrap comprehensions in parenthesis when building arrays, because
items = (item for item in list when x is y)
.In
toJSON_2
the first line is being interpreted asYou can't blame coffeescript for that, as the intent is not clear. My advice is to follow a simple guideline: Anything that would confuse a human will very likely confuse the parser.
That includes wrapping expressions in parenthesis, using explicit
return
s, brackets for object literals, temporary variables and whatever you need to make your intentions clear in code.修复 #1871 和 #1903 过早。
A consequence of fixing #1871 and #1903 prematurely.
这是我作为一名程序员的观点,但不是作为一个真正使用过 CoffeeScript 的人的观点(到目前为止,我已经对它进行了相当深入的研究):编程时,你的一般努力应该是使你的代码的含义尽可能明显和明确(尽管也可能有其他重要的事情,所以这并不总是最重要的目标)。
当你遇到这样的令人讨厌的区域时(有些 CoffeeScript 的人会知道,有些则不会 - 在这种情况下,我碰巧在尝试使用它之前在研究 CoffeeScript 时读到过它),花括号使它更加更加明显且明确。而对于另一个,你会留下一个脆弱的结构,初学者会对其进行看似完全无害的更改,但这会完全破坏它(你可能没有意识到这一点,然后调试将非常 困难)。
Here is my opinion as a programmer but not as one who has actually used CoffeeScript yet (looking into it fairly deeply is as far as I've gone so far): when programming, your general endeavour should be to make the meaning of your code as obvious and unambiguous as you can (though there can be other important things too, so this won't always be the most important goal).
When you hit yucky regions like that (which some CoffeeScript people will know about and some won't—in this case, I happen to have read of it in doing my research on CoffeeScript before trying to use it), the curly braces make it much more obvious and distinctly unambiguous. Whereas with the other, you're left with a fragile structure which a beginner will make a seemingly entirely innocuous change to but which will break it completely (and you might not realise it, and debugging will then be very difficult).