如何在标量上下文中使用菱形运算符作为函数调用参数?

时间:2011-03-17 16:15:40

标签: perl diamond-operator

如何直接将菱形运算符中的值传递给函数(sub)?

我试过了:

#!/usr/bin/perl
use Math::Complex;

#quadraticEq - quadratic equation with parameters a ,b ,c
sub quadraticEq {
    print "\nx1= ", 
      ($_[1]*$_[1]-sqrt($_[1]*$_[1]-4*$_[0]*$_[2]))/(2*$_[0]),
      "\nx2= ",
      ($_[1]*$_[1]+sqrt($_[1]*$_[1]-4*$_[0]*$_[2]))/(2*$_[0]);
}

print 'Enter Numbers:';
quadraticEq(<>,<>,<>); #here

但是当我为每个函数参数输入数字时,我需要输入EOF。它表现为@array=<>。我希望它的行为类似于$var=<>。因此输入应如下所示:

Enter Numbers: 5 4 3

4 个答案:

答案 0 :(得分:6)

在我帮助您解决问题时,我将向您展示几个最佳做法......

#!/usr/bin/perl

use strict;     # strict/warnings helps detect lots of bugs and logic issues,
use warnings;   # so always use them

use Math::Complex; # WHITESPACE IS YOUR FRIEND

#quadraticEq - quadratic equation with parameters a ,b ,c

sub quadraticEq{
    # Shift out your subroutine variables one at a time, or assign them to a list.
    my ($a, $b, $c) = @_;

    print "\nx1= ", 
      ($b*$b-sqrt($b*$b-4*$a*$c))/(2*$a), # You're wrong on your formula btw
      "\nx2= ",
      ($b*$b+sqrt($b*$b-4*$a*$c))/(2*$a);
}

print 'Enter Numbers: ';

# Perl only supports reading in a line at a time, so... if you want all your
# inputs on one line, read one line.
# EDIT: That's not strictly true, since you can change the input record separator,
# but it's just simpler this way, trust me.

my $line = <>;

# Then you can split the line on whitespace using split.
my @coefficients = split /\s+/, $line;

# You should check that you have at least three coefficients and that they
# are all defined!

quadraticEq(@coefficients);

答案 1 :(得分:5)

在函数参数列表中的裸<>运算符始终在列表上下文中调用。但是有很多方法可以强制你想要的标量上下文:

quadraticEq(scalar <>, scalar <>, scalar <>);
quadraticEq("" . <>, "" . <>, "" . <>);
quadraticEq(0 + <>, 0 + <>, 0 + <>);  # if you want to evaluate as numbers anyway

请注意,标量上下文中的<>将从输入读取到下一个“记录分隔符”。默认情况下是系统的换行符,因此上面代码的默认行为是从每行读取单独的值。如果(如原始帖子所示)输入是空格分隔的并且全部在一行上,那么您将需要:

  1. 在调用$/ = " "之前将记录分隔符设置为空格(<>),或
  2. 使用其他方案,例如split将输入行解析为单独的值
  3. # read a line of input and extract 3 whitespace-separated values
    quadraticEq( split /\s+/, <>, 3 );
    

    对于这样的问题,我几乎总是选择#2,但是有多种方法可以做到。

答案 2 :(得分:2)

通常,在将值传递给子例程时,Perl使用列表上下文,因此您正在使用&lt;&gt;与

相同
my @args = (<>, <>, <>);

显然,这不是你想要的!

您可以使用scalar关键字强制标量上下文:

my @args = ( scalar <>, scalar <>, scalar <>); # read one

或者,将它们全部读入变量,以便人们知道您的意图:

my $first = <>;
my $second = <>;
my $third = <>;

另外,在使用它们之前,你应该真正解析@_中的参数。它会让你的功能更加容易理解。一个例子:

sub quadratic2 {
    my ($a, $b, $c) = @_;
    ... # now use the actual symbols instead of array indexes
}

答案 3 :(得分:2)

quadraticEq(map scalar <>, 1..3);

另见perldoc -f readline