我目前正在从learn.perl.org学习Perl 5,我很好奇它的打字系统。我看到有关Perl弱或强类型的混合信息,并且它也是动态类型的。维基百科声称它也支持鸭子打字。
任何人都可以确认其弱或强类型的性质吗?
答案 0 :(得分:15)
我看到有关Perl弱或强类型的混合信息
这并不奇怪。关于C是强类型还是弱类型语言,也存在相互矛盾的信息。
静态但弱类型语言的示例是C. [source]
C 强烈类型... [source]
这适用于弱类型的语言,例如C. [source]
LISP引擎......本身通常用强类型的语言编写,如C ... [source]
使用弱类型的语言,例如C,... [source]
TYPE:强烈输入:(C,Algol,Fortran)[source]
Mark J Dominus compiled上面的列表,discovered有8种不兼容的定义,表明强类型的含义。
如果类型注释与变量名称相关联,而非使用值,则会强类型化语言。如果类型附加到值,则输入的类型为弱。
如果语言包含类型约束违规的编译时检查,则强类型语言。如果检查延迟到运行时间,则输入为弱。
如果语言包含编译或运行时检查,则类型约束违规将被强类型化。如果没有进行检查,则输入结构很弱。
如果禁止不同类型之间的转换,则会严格键入语言。如果允许进行此类转换,则会进行弱类型转换。
如果必须明确指出不同类型之间的转换,则会强类型输入语言。如果执行了隐式转换,则会进行弱类型化。
如果没有语言级别的方法来禁用或规避类型系统,则会强类型语言。如果有演员表或其他类型规避的机制,则输入的类型很弱。
如果语言具有复合类型的复杂,细粒度类型系统,则会强类型化。如果它只有几种类型,或者只有标量类型,则它是弱类型的。
如果语言的数据对象的类型是固定的且在对象的生命周期内不变,则会强类型化。如果数据的类型可以更改,则语言键入的类型很弱。
这表明“强类型”和“弱类型”是meaningless phrases。因此,这个答案的其余部分和所有其他答案实际上只是对你所要求的猜测。
Perl弱或强类型?
它有强类型(标量,数组,散列等)和弱类型(字符串,浮点数,有符号整数,无符号整数,引用等)。
这是基于上面列表中的定义#1,#2,#4,#5和#6。
维基百科声称它也支持鸭子打字。
方法调用使用动态绑定(duck typing)。
这是明确的。
答案 1 :(得分:5)
如果使用'strong typed'的定义,则意味着您指定变量保存的数据类型 - perl不是。
它基本上有一种类型 - 标量 - 可以容纳各种不同的数据类型。 Perl根据它的“外观”推断操作的正确性。 (它还有散列和数组 - 这是一组标量)
因为你可以:
#!/usr/bin/env perl
use strict;
use warnings;
my $value = 42;
#concat 0 onto the end.
$value .= 0;
print $value,"\n";
#numeric add
$value += 1;
print $value,"\n";
#division - to create a float.
$value = $value / 4;
print $value,"\n";
#string replacement on a float.
$value =~ s/\.25//g;
print $value,"\n";
在字符串和数字之间来回隐式地转换$value
,并且它“正常工作” - 我将其称为弱类型。
由于类型不匹配,这些操作......在强类型语言中不起作用(您期望的方式)。
有一点值得一提的是context的概念。 Perl是一种上下文敏感语言,因为它可以从上下文中推断出你的意思。
因此,如果您只是打开并从文件句柄中读取:
open ( my $input, '<', "some_file.txt" ) or die $!;
my $line = <$input>;
这将从$input
读取一行,因为它正在标量上下文中进行读取。
如果您改为:
my @lines = <$input>;
因为您正在列表上下文中工作,所以文件的整个部分将被读入数组@list
。
您可以使用wantarray()
显式测试上下文(这是一个用词不当 - 它应该是wantlist
):
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
sub context_test {
if ( wantarray() ) {
return ( "some", "results", "here", "(list context)" );
}
else {
if ( defined wantarray() ) {
return "some results (scalar context)";
}
else {
print "called in a void context\n";
}
}
}
my $first = context_test;
print Dumper \$first;
my @second = context_test;
print Dumper \@second;
context_test;
我认为我也认为这是一个弱类型的例子,因为perl 尝试根据上下文找出正确的事情。有时它确实弄错了。
所以你可以:
print "Elements are:", @second, "\n"; # prints elements from the array.
print "Count is", scalar @second,"\n"; #prints number of elements in array.
if ( @second > 2 ) {
print "Array \@second has more than 2 elements\n";
}
我提到它的原因是(除了注释)上下文也可能被运营商类型强制。
$first .= @second; #forces scalar context due to concat operation.