“如何提高运营商的竞争力”+&引用;在perl中

“如何提高运营商的竞争力”+&引用;在perl中,perl,Perl,希望增强perl中的运算符“+”,以便在两个操作数都是数字时,它将是常规的加法运算 $a = 11; $b = 12; $x = $a + $b; #expect it to be 23 如果一个操作数是字符串,则将所有操作数转换为字符串,并将其视为串联 $a = 11; $b = " cars"; $x = $a + $b; #expect it to be "11 cars" 如果这是不可能的,想知道是否有可能为我创建一个新的运营商来做这件事 这毫无意义。例如,以下输出应该是什么 my

希望增强perl中的运算符“+”,以便在两个操作数都是数字时,它将是常规的加法运算

$a = 11;
$b = 12;
$x = $a + $b; #expect it to be 23
如果一个操作数是字符串,则将所有操作数转换为字符串,并将其视为串联

$a = 11;
$b = " cars";
$x = $a + $b; #expect it to be "11 cars"

如果这是不可能的,想知道是否有可能为我创建一个新的运营商来做这件事

这毫无意义。例如,以下输出应该是什么

my $x = 11;    print("$x\n");
my $y = 12;    print("$y\n");

print($x+$y, "\n");

my $m = "11";  print(0+$m, "\n");
my $n = "12";  print(0+$n, "\n");

print($m+$n, "\n");
请记住,
$x
$m
是相同的(它们都包含一个数字和一个字符串),
$y
$n
也是相同的

SV = PVIV(0x16f2dd8) at 0x16fe8b0      $x
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 11
  PV = 0x16f7b30 "11"\0
  CUR = 2
  LEN = 16
SV = PVIV(0x16f2e20) at 0x16fea60      $m
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 11
  PV = 0x17086b0 "11"\0
  CUR = 2
  LEN = 16
SV = PVIV(0x16f2df0) at 0x16fe8f8      $y
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 12
  PV = 0x171eee0 "12"\0
  CUR = 2
  LEN = 16
SV = PVIV(0x16f2e08) at 0x170eee8      $n
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 12
  PV = 0x17320e0 "12"\0
  CUR = 2
  LEN = 16

Perl不区分变量类型。这与shell脚本和awk脚本的工作方式非常一致。变量可以是程序中某个位置的数字,也可以是另一个位置的字符串。Perl希望您知道自己在做什么:

#! /usr/bin/env perl
#

use strict;
use warnings;
use feature qw(say);

my $vendor_id = "344";
my $inventory_item = "23942";

print "You want to order item ";
print $vendor_id + $inventory_item;
print "\n";
这将打印:

You want to order item 24286
它将我的
$vendor\u id
添加到我的
$inventory\u项目中
。您可能想做的是连接它们

Perl无法判断变量是字符串还是数字,因此Perl强制您使用运算符。
+
是数字加法,
是字符串串联。在许多语言中,这将是同一个运算符,但在Perl中,我们需要两个不同的运算符。要想做你想做的事,你应该这样做:

print $vendor_id . $inventory_item;
vs

这就是为什么Perl有两组完全不同的布尔运算符:一组用于数值比较,另一组用于字符串。这为Perl提供了极大的灵活性,因为变量可以在一个位置被视为数字,然后在另一个位置被视为字符串。然而,这也意味着您更好地了解您的变量应该代表什么

在Python、Java、Swift和许多其他语言中,可以将变量声明为字符串或数字。如果您将变量声明为字符串并尝试添加它们,或者将它们声明为某种形式的数字数据并尝试将它们连接起来,请注意。在大多数语言中,必须使用方法(如
int2sting
)或声明将变量从一种形式转换为另一种形式

如果你真的不知道你的数据,也不确定它代表什么,你可以使用
looks\u like\u number
from。这不是一个内置函数,但
Scalar::Util
是一个标准模块,可能已经存在于您的Perl发行版中:

use strict;
use warnings;
use feature qw(say);

use Scalar::Util qw(looks_like_number);
my $first = "11";
my $second = " of cars";

if ( looks_like_number($first) and looks_like_number($second) ) {
    say $first + $second;   # Add the two numbers together
}
else {
    say $first . $second;   # At least one is a string, so concatenate them
}
现在,如果
$first
$second
看起来都像数字,那么它们将被添加。但是,如果一个或另一个看起来不像一个数字,它们将被连接起来

有一些Perl模块(我记不起来了)将把Perl变成一种声明性语言,在这种语言中,变量被告知是字符串、整数、浮点数等。由于许多原因,这些尝试中的大多数都是不完整的。例如,您无法阻止某人使用更模糊的内置语法

如果您有更高级的Perl知识,您可以创建自己的对象类型,并使用
重载
pragma重载每个类类型的操作定义:

use strict;
use warnings;
use feature qw(say);

use Object::Perl;    # Hypothetical module

my $first  = Object::Perl::String->new(11);
my $second = Object::Perl::String->new(" cars");

say $first + $second;    # Overloaded "+" to concatenate two Object::Perl::String types

$first  = Object::Perl::Int->new(11);
$second = Object::Perl::Int->new(12);

say $first + $second;   $ Overloaded "+" to add two Object::Perl::Int types

然而,如果你正在经历所有这些麻烦,你最好学习Python。

参见。对于
+
,基本上,不,你不能这样做。您可以使用重载更改运算符在对象上的工作方式,但不能更改它们在非引用标量上的工作方式。你不能在Perl中创建新的操作符,尽管它允许你伪造它。Perl的设计目的是让它的操作符被视为单态的,它的数据类型被视为多态的(大部分)。你的愿望是扭转这种局面。你最终会发明很多启发式方法来决定一个标量值应该被视为一个字符串还是一个数字。这是人们往往无法就每种情况下的正确规则达成共识的问题之一。想知道在什么情况下你想要这种行为。如果你做算术,你就不会;我不需要字符串,当需要字符串连接时,为什么需要算术?你能告诉我想要实现什么吗?谢谢大家的想法,操作数只是普通的标量,perl代码只是传递给我的代码进行计算,所以我不能做太多(包括重载)。中缀看起来很有趣,我要学习它。谢谢大卫的详细回答!希望它能像javascript一样具有所需的行为。@codingFun:那是因为javascript就是这样设计和编写的。要让JavaScript像Perl那样工作,您将面临一项非常困难的工作。如果说有什么区别的话,Perl更灵活。在任何情况下,为什么要为加法和字符串连接编写
+
?这只是为了让您不必记住其他语法吗?@Borodin,当我编写perl脚本时,我会适当地使用“+”和“.”。当我从有javascript经验的人那里继承perl代码时,很多时候错误是由于perl中的运算符“+”与javascript中的运算符“+”混淆造成的。@codingFun:这是使用运算符多态性的可怕原因。您应该修复错误代码,而不是让它看起来像是工作的。@编码乐趣JavaScript的问题是,如果变量没有定义为特定类型,您不知道它将如何处理
+
。我可能需要一个加法,但它会在不报告错误的情况下进行串联。或者,一种语言应该有固定的数据类型(像在其他脚本语言中),或者该语言应该避免多态和不明确的运算符(像Perl和Bash)。按位和/或/异或运算符可以根据其操作数的类型进行不同的操作。@Borodin,它们不行。他们是马车。通常需要从变量中创建数字并将其传递给运算符,而不是直接使用运算符。
use strict;
use warnings;
use feature qw(say);

use Scalar::Util qw(looks_like_number);
my $first = "11";
my $second = " of cars";

if ( looks_like_number($first) and looks_like_number($second) ) {
    say $first + $second;   # Add the two numbers together
}
else {
    say $first . $second;   # At least one is a string, so concatenate them
}
use strict;
use warnings;
use feature qw(say);

use Object::Perl;    # Hypothetical module

my $first  = Object::Perl::String->new(11);
my $second = Object::Perl::String->new(" cars");

say $first + $second;    # Overloaded "+" to concatenate two Object::Perl::String types

$first  = Object::Perl::Int->new(11);
$second = Object::Perl::Int->new(12);

say $first + $second;   $ Overloaded "+" to add two Object::Perl::Int types