Perl5和Perl6对比使用Sigils的差别
我们将看到Sigls(变量名称开头处的符号)Perl5和Perl6之间的差别。
概述
让我们从Perl5和Perl6中的Sigils概述开始:
@(Arrayvs.Positional)
在perl5中定义数组时,可以创建一个可扩展的标量值列表,并给它一个带有sigil的名称。@:
#Perl5 my@foo=(1,2,3); push@foo,42; sayfor@foo;#12342
在perl6中定义数组时,将创建一个新的列阵对象和绑定它以词法垫中的那个名字输入条目。因此:
#Perl6 my@foo=1,2,3; push@foo,42; .sayfor@foo;#12342
在功能上与Perl5中相同。然而,第一行是用于:
#Perl6 my@foo:=Array.new(1,2,3);
这将绑定(而不是赋值)一个新的列阵对象指向词汇定义的名称。@foo。这,这个,那,那个@perl6中的sigil表示一个类型约束:如果您想用该sigil将某个东西绑定到lexpad条目中,则它必执行位置角色。要确定一个类是否使用SmartMatch执行某个角色并不困难:
#Perl6 sayArray~~Positional;#True
您可以认为perl6中的所有数组都是以与绑定阵列在Perl5中实现。而这也离事实不远。如果不深入细节,一个简单的例子可能会澄清这一点。这,这个,那,那个at-POS方法是实现位置角色。每当需要访问单个元素时,都会调用此方法。所以,当你写:
say@a[42]
你正在执行:
say@a.AT-POS(42)
当然,这不是唯一可以实现的方法;更多.
而不是必须绑定您的类来执行位置角色,有一种特殊的语法使用是特质。所以不必写:
#Perl6 my@a:=YourClass.new(1,2,3);
你可以写:
#Perl6 my@aisYourClass=1,2,3;
在Perl5中,绑定数组比“普通”数组慢得多。在Perl6中,数组在启动时同样缓慢。幸运的是,rakudoperl6通过内联和“在定时”(Jiting)优化热代码路径。操作码在可能的情况下使用机器代码。(由于优化器的进步,这种情况发生得更快、更频繁、更好)。
%(Hashvs.Associative)
Perl6中的散列实现类似于数组;您还可以将它们视为绑定散列(使用Perl5术语)。而不是位置用于实现数组的角色,则结合性角色应用于实现散列。
同样,一个简单的例子可能会有所帮助。关键方法是实现结合性角色。每当需要访问特定键的值时,都会调用此方法。所以,当你写:
say%h
你正在执行:
say%h.AT-KEY("foo")
当然,有许多其他方法你可以实现。
&(Subroutinevs.Callable)
在Perl5中,只有一种可调用的可执行代码,即子程序:
#Perl5 subfrobnicate{shift**2}
而且,如果要将子例程作为参数传递,则需要获得对它的引用:
#Perl5 subdo_stuff_with{ my$lambda=shift; &$lambda(shift); } saydo_stuff_with(\&frobnicate,42);#1764
在Perl6中,多种类型的对象可以包含可执行代码。他们的共同点是他们消耗了可赎回角色.
Sgil强制绑定到执行可赎回角色,就像%信号与结合性角色和@信号与位置角色。一个与Perl5非常接近的例子是:
#Perl6 my&foo=sub($a,$b){$a+$b} sayfoo(42,666);#708
注意,即使变量具有&Sigil,你知道不需要使用它来执行该变量中的代码。实际上,如果您在开始与普通的人相比,没有什么区别分声明:
#Perl6 BEGINmy&foo=sub($a,$b){$a+$b}#sameassubfoo()
与Perl5不同的是,在Perl6中,开始块可以是没有块的单个语句,因此它与外部共享其词法范围。但我们将在以后的文章中更多地讨论这个问题。
使用&变量是在编译时知道某物可执行文件,即使某物还不知道。
还有其他方法可以设置一段代码以供执行:
#Perl6 my&boo=->$a,$b{$a+$b}#same,usingaBlockwithasignature my&goo={$^a+$^b}#same,usingauto-generatedsignature my&woo=*+*;#same,usingWhatevercurrying
还可以使用&在签名内签名以表示被调用者希望在那里执行什么东西。这使我们回到本节中的前两个代码示例:
#Perl5 subfrobnicate{shift**2} subdo_stuff_with{ my$lambda=shift; &$lambda(shift); } saydo_stuff_with(\&frobnicate,42);#1764
#Perl6 subfrobnicate{$^a**2} subdo-stuff-with(&lambda,$param){lambda($param)} saydo-stuff-with(&frobnicate,42);#1764
注意,在Perl6中,您不需要接受引用;您可以简单地传递代码对象如&作为参数。
$(Scalarvs.Item)
与@、%和&Sigils相比,$sigil有点平淡。它不强制执行任何类型检查,因此可以将其绑定到任何类型的对象。因此,当你写:
#Perl6 my$answer=42;
像这样的事情发生了:
#Perl6 my$answer:=Scalar.new(42);
除了在一个很低的水平。因此,如果您想知道,此代码将无法工作。当你声明标量变量时,就是这样。
在Perl6中,$还指出,其中的任何内容都应被视为单一的项目。因此,即使标量容器中填充了列阵对象时,在需要迭代的情况下,它将被视为单个项:
#Perl6 my@foo=1,2,3; my$bar=Array.new(1,2,3);#alternately:[1,2,3] .sayfor@foo;#123 .sayfor$bar;#[123]
请注意,后一种情况只适用于一迭代VS三在前一种情况下。您可以通过前缀适当的sigil来指示是否要迭代某些内容:
#Perl6 .sayfor$@foo;#[123],considerthearrayasanitem .sayfor@$bar;#123,considerthescalarasalist
但也许这会把我们带到噪音太远的地方。幸运的是,还有更详细的等价物:
#Perl6 .sayfor@foo.item;#[123],considerthearrayasanitem .sayfor$bar.list;#123,considerthescalarasalist
*(Typeglobs)
正如您可能已经注意到的,Perl6没有*sigil或typeglobs的概念。如果你不知道是什么类型的球体,你不必担心这个。您可以很好地度过难关,而不必知道Perl5中复杂的符号表(也可以跳过下一段)。
- 在Perl6中,Sigil是存储在符号表中的名称的一部分,而在Perl5中,名称是在没有信号的情况下存储的。例如,在Perl5中,如果在程序中引用$foo,编译器将查找foo(没有sigil),然后获取相关信息(这是一个数组),并查找它所需的$sigil索引。在Perl6中,如果引用$foo,编译器将查找$foo并直接使用与该键相关的信息。
请不要混淆用于表示Perl6中的参数与Perl5中的TypeGulbSIGL的SLurpy,它们彼此没有任何关系。
Sigillessvariables
Perl5不支持无符号变量(除了可能的左值子程序,但这确实非常笨拙)。
Perl6也不直接支持Sigilless变量,但它支持通过前缀反斜杠(\)定义中的名称:
#Perl6 my\the-answer=42; saythe-answer;#42
由于赋值的右边是常量,这与定义常量基本相同:
#Perl5 useconstantthe_answer=>42; saythe_answer;#42 #Perl6 myconstantthe-answer=42; saythe-answer;#42
如果定义的右边是别的东西,那就更有趣了。就像一个容器!这允许使用以下语法技巧来获得无符号变量:
#Perl6 my\foo=$=41;#asigillessscalarvariable my\bar=@=1,2,3,4,5;#asigillessarray my\baz=%=a=>42,b=>666;#asigillesshash
这基本上是创建匿名词法实体(标量、数组和哈希),使用正常语义初始化它们,然后绑定生成的对象(标量集装箱列阵对象,以及散列对象)的名称,您可以将其用作Perl6中的任何其他普通变量。
#Perl6 say++foo;#42 saybar[2];#3 bar[2]=42; saybar[2];#42 saybaz;#(42666)
当然,这样做,您将失去所有的优势,特别是在插值方面。然后,您将始终需要使用{}在插值中。
#Perl6 say"Theansweris{the-answer}.";#Theansweris42.
在Perl5的大多数版本中,对应的内容更麻烦:
#Perl5 say"Theansweris@{[the_answer]}.";#Theansweris42.
当使用Perl5概念考虑这些变量时,Perl6中的所有变量都可以被视为绑定变量。这使得他们在一开始就有点慢。但是在某些基准测试中,运行时优化和热代码路径的JITting(从一点到机器代码)已经使其速度超过Perl5变量。
@,%,和&在Perl6中,不要创建任何特定的对象,而是指示一个类型约束,该约束将应用于名称绑定到的对象。$Sigil在这方面是不同的,因为没有要强制执行的类型约束。
@和$前缀分别表示实值化和项化,尽管使用.清单和.项目方法代替。
通过几个语法技巧,可以不用变量名称中的任何Sigl来编程Perl6。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。如果你想了解更多相关内容请查看下面相关链接
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。