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

问题描述 投票:0回答:3

我想围绕

printf(...)
编写一个包装器。

我的第一次尝试是:

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

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

有人知道解决办法吗?可能不使用任何特殊的软件包?

编辑:在真实情况下,我想使用

sprintf
。显然
printf
sprintf
之间有区别。

perl variadic-functions
3个回答
8
投票

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])

2
投票

这个怎么样

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

1
投票

许多命名运算符(例如

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 );   # Or just `printf`.
}

或者如果您想避免复制,

sub printf2 {
   print sprintf( $_[0], @_[ 1..$#_ ] );   # Or just `printf`.
}
© www.soinside.com 2019 - 2024. All rights reserved.