perl 子例程返回数组和 str 但它们正在合并

perl subroutine returning array and str but they are getting merged

sub process_feed {
    my ($line) = @_; 

    my @lines;
    my $last_received = ""; 

    while (1) {
        if ($line =~/^{(.*?)}(.*)/) {
            push @lines, ; 
            $line = ; 
        } else {
            $last_received = $line;
            last;
        }   
    }   

    print "sending back @lines, $last_received\n";

    return (@lines, $last_received);
}

my (@lines, $leftover) = process_feed("{hi1}{hi2}{hi3");
print "got lines: @lines\n";
print "got last_recevied, $leftover\n";

输出:

sending back hi1 hi2, {hi3
got lines: hi1 hi2 {hi3
got last_recevied, 

预期:

sending back hi1 hi2, {hi3
got lines: hi1 hi2 
got last_recevied, {hi3

为什么 $last_recevied 合并到 @lines
我如何在外部函数中拆分它们?

一个函数return是一个平面列表。如果一个数组在被赋值的变量列表中排在第一位,则整个列表都会进入该数组。所以在

my (@lines, $leftover) = process_feed("{hi1}{hi2}{hi3");

@lines 获得子 return 编辑的所有内容。

解决方案

  • Return 对数组的引用和一个标量,因此分配给两个标量

    sub process_feed { 
         # ...
         return \@lines, $last_received;
     }
     my ($rlines, $leftover) = process_feed("{hi1}{hi2}{hi3");
     print "got lines: @$rlines\n";
    

    一般来说,我会推荐这种方法。

  • 因为 $last_received 总是 returned,交换 return 和赋值

    中的顺序
    sub process_feed { 
        # ...
        return $last_received, @lines;
    }
    my ($leftover, @lines) = process_feed("{hi1}{hi2}{hi3"); 
    

由于分配给标量,因此首先只分配 return 中的一个值给它,然后其他值进入下一个变量。这是数组 @lines,它占用了所有剩余的 return.