我已经采用了编程类的原则,并且已经给出了一个Perl表达式,它将一个字符串编号连接到一个int编号,然后再添加一个数字,并且它的计算结果很好。即("4" . 3) + 7 == 50
。
我试图理解为什么Perl会这样做以及它可能带来什么问题。我很难掌握课堂上的许多概念,并试图从不同的来源获得解释,除了我可怕的老师和同样可怕的笔记。
这种表达背后的概念能否向我解释,以及他们可能提出的问题?在此先感谢您的帮助。
编辑:清晰度
答案 0 :(得分:4)
Perl是围绕“我的意思”的核心概念而建立的。
标量是一种多用途变量类型,用于隐式地将值转换为适合您正在执行的操作的数据类型。
这是有效的原因是因为perl对上下文敏感 - 它知道不同的预期返回值之间的差异。
在基本级别,您可以使用wantarray
功能查看此内容。 (如下所述 - 可能名字很糟糕,因为我们正在讨论LIST
上下文)
sub context_test {
if ( not defined wantarray() ) {
print "Void context\n";
}
if ( wantarray() ) {
return ( "List", "Context" );
}
else {
return "scalar context";
}
}
context_test();
my $scalar = context_test();
my @list = context_test();
print "Scalar context gave me $scalar\n";
print "List context gave me @list\n";
这个原则贯穿整个perl。如果需要,可以使用Contextual::Return
之类的东西来进一步扩展它 - 测试标量上下文的数字,字符串和布尔子集之间的差异。
我提到这一点的原因是因为标量是一种特殊的数据类型 - 如果你看Scalar::Util
,你会看到创建dualvar
的能力 - 一个具有不同值的标量不同的背景。
my $dualvar = Scalar::Util::dualvar ( 666, "the beast" );
print "Numeric:",$dualvar + 0,"\n";
print "String:",$dualvar . '',"\n";
现在,搞乱使用dualvars是一个很好的方法来创建一些非常烦人且难以追踪的错误,但关键是 - scalar
是一种神奇的数据类型,并且perl总是知道你是什么&#39 ;做结果。
如果执行字符串操作,perl会将其视为字符串。如果执行数字运算,perl会尝试将其视为数字。
my $value = '4'; #string;
my $newvalue = $value . 3; #because we concat, perl treats _both_ as strings.
print $newvalue,"\n";
my $sum = $newvalue + 7; #perl turns strings back to numbers, because we're adding;
print $sum,"\n";
if ( Scalar::Util::isdual ( $newvalue ) ) { print "newvalue Is a dual var\n" };
if ( not Scalar::Util::isdual ( $sum ) ) { print "sum is NOT a dual var\n"; };
主要是' context'是在perl的幕后发生的事情,你不必担心它。如果您来自编程背景,int
和string
之间隐式投射的想法可能看起来有点脏。但它大部分工作正常。
您可能偶尔会遇到以下错误:
Argument "4a3" isn't numeric in addition (+)
这种方法的一个缺点是这些是运行时错误,因为你没有在“编译”中进行强类型检查。时间。
所以就具体问题而言:
您是运行时类型检查,而不是编译时间。如果您有严格的类型,则可以在开始运行任何内容之前检测到尝试将string
添加到int
。
您并不总是在您认为自己存在的环境中运行,这可能会导致一些不可预测的行为。最好的例子之一是print
在列表上下文中运行 - 所以举个例子:
print context_test();
您将获得List Context
。