通过子程序拼接数组

ak1*_*234 0 perl subroutine

splice我正在尝试对数组使用子例程。我究竟做错了什么?

$foo = 123223;
@data = split(//, $foo);
splice_data(\@data);
printf(@data);

sub splice_data{
    splice(@data,3,1,1);
    return @data;
}
Run Code Online (Sandbox Code Playgroud)

输出:1

预期输出:123123

zdi*_*dim 5

问题中的代码有多个严重问题

  • 数据被传递给子系统,但子系统不会读取(也不使用)该数据

  • Sub直接使用恰好在其范围内看到的数据

  • Sub 传递了一个引用,似乎用于更改调用者中的数据,但返回该数据的平面列表

相反,我们通常希望子程序具有明确定义的输入,通过@_读取。它可以通过使用传递给它的数据引用(如果传递给它)直接更改调用者中的数据来返回其结果,或者通过显式return-ing 数据(或两者)

use warnings;
use strict;
use feature 'say';

sub splice_data {
    my ($ref_to_data) = @_;

    splice @$ref_to_data, 3, 1, 1;

    return 1;  # for "success"
}

my $foo = 123223;

my @data = split //, $foo;

splice_data(\@data);

say "@data";
Run Code Online (Sandbox Code Playgroud)

还有一些评论

  • 没有严格警告始终将它们放在程序的开头。它们有直接的帮助,可以避免各种错误,并且通常会推动改进各种编程实践

  • 一般来说,最好在程序的顶部定义子程序,这样它们就不会意外地“看到”在它们之前定义的数据(但只能使用专门传递给它们的数据)

  • 使用一般打印功能 ,或者在不需要换行的情况下进行打印。仅当需要特定格式时才使用printfsay

从这里的许多链接可以明显看出,我建议阅读所涉及的所有内容的文档。


问题的代码恰好按预期工作,只是打印错误,了解如何执行是有启发性的。在printf的通常调用中,在可选文件句柄之后,第一个参数是格式规范,然后是格式化时使用的内容列表。

由于数组首先被评估为一个列表,printf我们有

printf @data --> printf 1,2,3,1,2,3
Run Code Online (Sandbox Code Playgroud)

其中第一个参数1是“格式”,列表2,3,1,2,3是(大概)格式规范使用的项目。格式规范由格式化代码(如%s%5.2f等,请参阅sprintf)和要打印的文字字符组成——而这个只有要1打印的文字。