使用可变参数作为sprintf的参数

时间:2012-03-31 18:53:36

标签: perl variadic-functions

我想围绕printf(...)编写一个包装器。

我的第一次尝试是:

sub printf2 {
    my $test = sprintf(@_);
    print $test;
}

由于数组(在标量上下文中)不是格式字符串,因此不起作用(如预期的那样)。

有谁知道解决方案?可能没有使用任何特殊包装?

编辑:在真实环境中,我想使用sprintf。显然printfsprintf之间存在差异。

3 个答案:

答案 0 :(得分:7)

sprintf函数有一个($@) prototype,因此sprintf的第一个参数始终在标量上下文中进行求值,即使它是一个数组。

$x = sprintf(@a);      # same as  sprintf(scalar @a)

因此,在调用sprintf之前,需要将模板与其余参数分开。 这是一个简洁的方法:

sub printf2 {
    my $test = sprintf(shift, @_);
    print $test;
}

奇怪的是,printf没有原型并且达到预期目的。

printf(@a);            # same as  printf($a[0], @a[1..$#a])

答案 1 :(得分:2)

这个怎么样

sub pf { printf $_[0],@_[1..$#_] }

答案 2 :(得分:0)

许多named operators(例如sprintf)都有特殊的语法。 sprintf的语法定义为

sprintf FORMAT, LIST

通常(但并非总是)可以使用prototype来查看。

>perl -wE"say prototype 'CORE::sprintf'"
$@

问题是您使用了以下语法之一而不是记录的语法。

sprintf ARRAY
sprintf LIST

只需切换到记录的语法即可解决您的问题。

sub printf2 {
   my ($format, @args) = @_;
   print sprintf($format, @args);
}

或者如果你想避免复制,

sub printf2 {
   print sprintf($_[0], @_[ 1..$#_ ]);
}