【问题标题】:Concerns with concatenating strings and ints关于连接字符串和整数的问题
【发布时间】:2015-01-28 07:14:39
【问题描述】:

我学习了编程课程的原理,并获得了一个 Perl 表达式,它将一个字符串数字连接到一个 int 数字,然后将另一个数字添加到它上面,它的计算结果很好。即("4" . 3) + 7 == 50

我试图理解 Perl 为什么这样做以及它可能带来什么问题。我很难掌握课堂上的许多概念,除了我可怕的老师和同样可怕的笔记之外,我还试图从不同的来源获得解释。

能否向我解释这种表达背后的概念以及他们可能提出的担忧?在此先感谢您的帮助。

编辑:为了清晰

【问题讨论】:

  • 请在提问时更加努力,并提供您有问题的代码,以及您对代码的期望
  • ("4" ++ 3) + 7 = 50 不是有效的 Perl 代码(它甚至不能编译),所以我不知道你为什么说“它评估得很好”。正如@Сухой27 所说,请显示您遇到问题的实际代码。
  • 上面的表达式不是Pearl,而是翻译成Perl可以编译。代码不存在我只是在寻找对此表达式背后概念的解释(然后将字符串编号连接到 int)以及如何添加 int。
  • 字符串连接是使用. 运算符完成的,而不是+++,所以听起来您想知道为什么表达式("4" . 3) + 7 的计算结果为50。跨度>
  • 没错,我为我的菜鸟道歉,努力学习。

标签: perl concatenation


【解决方案1】:

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";

现在,搞乱双变量是创建一些非常烦人且难以追踪的错误的好方法,但重点是 - scalar 是一种神奇的数据类型,perl 总是知道你在做什么结果。

如果您执行字符串操作,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"; };

大多数情况下,“上下文”是在 perl 中发生在幕后的事情,您不必担心它。如果您有编程背景,那么在intstring 之间进行隐式转换的想法可能看起来有点脏。但它大多工作正常。

您可能偶尔会遇到以下错误: Argument "4a3" isn't numeric in addition (+)

这种方法的一个缺点是这些是运行时错误,因为您没有在“编译”时进行强类型检查。

所以就具体问题而言:

  • 您是在运行时类型检查,而不是编译时。如果您有严格的类型,您可以在开始运行任何内容之前检测到尝试将string 添加到int

  • 您并不总是在您假设的环境中进行操作,这可能会导致一些不可预测的行为。最好的示例之一是 print 在列表上下文中运行 - 以上面的示例为例:

    print context_test();

您将收到List Context

  • 如果您随意使用上下文相关的返回类型,您可能会创建一些非常烦人的错误,这些错误会极大地刺激回溯和故障排除。

【讨论】:

  • 很好的答案,虽然我认为那是List Context(而wantarray 有一个不幸的名字)
  • 是的,你说的很对。为了清楚起见,我将进行修改。 (我承认,有时我的大脑中往往会混淆这两者)
猜你喜欢
  • 1970-01-01
  • 2022-11-08
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
  • 1970-01-01
相关资源
最近更新 更多