这有效:
$_ =
say "hi";
Run Code Online (Sandbox Code Playgroud)
也就是说,您可以在分配和后面的内容之间放置任意数量的空格,它只会忽略它。您也可以使用任何变量(带有my)。有效地,将为$ _分配的结果say,即True。
这是令人惊讶的,但是符合规范,还是仅仅是令人惊讶?
运算符的两边可能有任意数量的空格。从而:
say 1
+ 2
+ 3;
Run Code Online (Sandbox Code Playgroud)
就编译器而言,它与以下内容完全相同:
say 1 + 2 + 3;
Run Code Online (Sandbox Code Playgroud)
赋值(=)只是另一个运算符,因此也要遵循以下规则。
此外,say这只是一个普通的内置子例程,因此就像:
my $answer = flip '24';
say $answer; # 42
Run Code Online (Sandbox Code Playgroud)
除非有更多的空格:
my $answer =
flip '24';
say $answer; # 42
Run Code Online (Sandbox Code Playgroud)
有一些在Perl 6中,其中空白是显著的地方,但缀运营商之间的空白是不是其中之一。
TL;DR P6 语法是自由格式。
\n\n\n\n\n悬空主题(或任何其他)变量不会失败
\n
您描述的问题是一个非常普遍的问题。这绝对不仅仅是变量声明/赋值!
\n\n在 P6 中,对语句的解析——单个命令单元(“执行此操作”)——通常会继续进行,直到到达显式语句分隔符——;这会将语句结束,就像句点 (又名句号)位于这个英语句子的末尾。
\n\n\n你可以放置任意数量的空格
\n
与许多编程语言一样,标准 P6 通常是自由格式的。也就是说,只要某些空白有效,那么通常任何数量的空白(水平和垂直空白)在语法上都是等效的。
\n\n$_ =\n\nsay "hi";\nRun Code Online (Sandbox Code Playgroud)\n\n如果有人应用自由格式原则,上面的工作原理与预期的完全一样——它是一个将 的值分配给say变量的单个语句$_。
\n\n\n这是令人惊讶但符合规范,还是只是令人惊讶?
\n
我喜欢发明(希望是简洁的)谚语。我刚刚发明了“惊喜随之而来”。
\n\n它符合规格。我知道要期待它。这并不令我惊讶。
\n\n如果有人接受 P6 通常是自由格式并且有分号语句分隔的事实,那么我预测,(最终 - 可能很快)将不再令人惊讶。
\n\n以上是对你问题的直接回答。另请参阅乔纳森的回答以了解更多类似内容。请随意忽略这个答案的其余部分。
\n\n对于这个答案的其余部分,我使用“自由格式”来指代 P6 的自由格式语法、分号语句分隔和花括号块 ( {...}) 的组合。
这个答案的其余部分分为三个部分:
\n\nP6 自由格式语法的例外情况
自由形式与线条导向
自由形式和面向线条?
@Larry 得出的结论是,直觉、美观、方便和/或其他因素证明在少数情况下标准 P6 中的纯自由格式语法的例外是合理的。
\n\n如果语句符合以下条件,则可以省略尾随分号:
\n\n是源文件或块中的最后一条语句;
以一个块结束,该块的结束卷曲后跟一个换行符(忽略注释)。
因此,下面的三个语句(theif和两个says)都不需要结束分号:
if 42 {\n say \'no semicolon needed before the closing curly\'\n} # no semicolon needed after the closing curly\nsay \'no semicolon needed if last statement in source file\'\nRun Code Online (Sandbox Code Playgroud)\n\n有时这可能不是我们想要的:
\n\n{ ... } # the closing } ends the statement (block)\n.() # call is invoked on $_\nRun Code Online (Sandbox Code Playgroud)\n\n改变它的一种方法是使用括号:
\n\n({ ... })\n.() # calls the block on prior line\nRun Code Online (Sandbox Code Playgroud)\n\n对于某些结构,空间要么是必需的,要么是不允许的。例如,某些后缀必须直接跟随它们所应用的值,而某些中缀则不能。这些都是语法错误:
\n\nfoo ++\nfoo\xc2\xab+\xc2\xbbbar\nRun Code Online (Sandbox Code Playgroud)\n\n对于某些编码场景,P6 的自由格式语法可以说是一个强大的净积极因素,例如:
\n\n1.内衬可使用块;
FP 代码是自然的(可以编写不平凡的闭包);
更直接的编辑/重构/复制/粘贴。
但也有缺点:
\n\n自由格式语法的写入和读取开销——分号和大括号。
忽略可能导致您发布问题的直觉。
后者是有力的。以下所有内容都可能导致某人认为say示例中的 是新语句的一部分,而不是该$_ =语句的延续:
=;之后的换行符
之后的空行;
say行首相对于行缺少缩进$_ =;
的性质say(它可能看起来say必须是一个新语句的开始)。
上述直觉的一个结果是,一些编程语言采用“面向行”的语法而不是自由格式的语法,其中最著名的是 Python。1
\n\n某些语言,例如 Haskell,允许使用面向行或自由格式的语法(至少对于某些语言结构而言)。
\n\nP6 支持俚语、改变语言的用户层模块。想象一个同时支持自由格式和面向行代码的俚语:
\n\n那些学习 P6 的人会遇到更多的熟悉感和更少的惊喜,因为他们根据自己的喜好专注于面向行或自由格式的代码来学习该语言的基础知识;
熟悉 P6 的人可以使用面向行或自由格式语法编写更好的代码。
冒着使事情过于复杂的风险,想象一个俚语不仅采用行方向,而且采用 Python 支持的越位规则no strict;,并实现非类型化无符号变量(它删除声明符和符号并提高不变性)。这是我几周前在Reddit 评论中发布的用想象中的俚语编写的一些代码片段:
sub egg(bar)\n put bar\n\ndata = ["Iron man", "is", "Tony Stark"]\ncallbacks = []\nRun Code Online (Sandbox Code Playgroud)\n\n也许像上面这样的事情太难实现了?(我目前不明白为什么。)
\n\n1本节的其余部分使用维基百科有关编程语言语句的部分作为指导来比较 P6 和 Python:
\n\n\n\n\n语句分隔符用于划分两个单独语句之间的边界。
\n
在 P6 中,它是;块的末尾。
在Python中;可以使用单独的语句。但它主要是面向线路的。
\n\n\n将行结束解释为语句结束的语言称为“面向行”语言。
\n
在 Python 中,行结束符终止一条语句,除非下一行被适当缩进(在这种情况下,它是关联子块的开始)或者显式的行继续符出现在行尾。
\n\nP6不是面向线路的。(至少,不是标准的 P6。我将在这个答案的末尾放置一个 P6 俚语,它支持自由格式和面向行的语法。)
\n\n\n\n\n“行延续”是面向行的语言中的一种约定,它允许单个语句跨越多行。
\n
Python 具有续行功能;有关详细信息,请参阅维基百科文章。
\n\n标准 P6 也具有行延续功能,尽管不是面向行的。2
\n\n2 P6 支持续行。继续引用维基百科的内容:
\n\n\n\n\n除非检测到行继续,否则换行符通常会导致将令牌添加到令牌流中。
\n
(标记是最小的代码片段——超出单个字符——被解析器视为原子单元。)
\n\n如果标准 P6 遇到换行符,则始终假定令牌中断,唯一的例外是跨行编写的字符串,如下所示:
\n\nsay\n\'The\n quick\n fox\';\nRun Code Online (Sandbox Code Playgroud)\n\n这将编译成功并在三个单独的行上显示The, quick, 和fox。
Python 中的等效项将生成语法错误。
\n\n\n\n\n反斜杠作为行的最后一个字符
\n
在 P6 中反斜杠:
\n\n不能出现在令牌的中间;
可用于在源代码中引入被解析器忽略的空格,以避免出现语法错误。例如:
say @foo\\\n \xc2\xbb++\nRun Code Online (Sandbox Code Playgroud)\n\n say @foo\\ \xc2\xbb++\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n某种形式的内联注释充当行延续
\n
这有效:
\n\nsay {;}#`( An embedded\ncomment ).signature\nRun Code Online (Sandbox Code Playgroud)\n\n嵌入的评论:
\n\n不能出现在令牌的中间;
不像反斜杠那么通用(say @foo#`[...]\xc2\xbb++不起作用)。
| 归档时间: |
|
| 查看次数: |
83 次 |
| 最近记录: |