我是perl的新手,无法找到有关我的问题的任何信息,所以如果这是重复或我完全出去吃午饭,请提前道歉。
实际问题略低一些。
#!/usr/bin/perl
use strict;
my @root = undef;
myfunc(\@root);
sub myfunc()
{
my ($ptr_parent) = @_;
print "root => ";
print \@root;
print "\n";
print "ptr_parent => $ptr_parent\n";
my @stuff = split(',', 'test1,test2,test3');
$ptr_parent = \@stuff;
print "stuff => ";
print \@stuff;
print "\n";
print "root => ";
print \@root;
print "\n";
print "ptr_parent => $ptr_parent\n";
}
毫不奇怪,我的输出如下:
root => ARRAY(0x7f903182e890)
ptr_parent => ARRAY(0x7f903182e890)
stuff => ARRAY(0x7f9031838548)
root => ARRAY(0x7f903182e890)
ptr_parent => ARRAY(0x7f9031838548)
我想要实现的目标如下:
root => ARRAY(0x7f903182e890)
ptr_parent => ARRAY(0x7f903182e890)
stuff => ARRAY(0x7f9031838548)
root => ARRAY(0x7f9031838548) <---- Note this changes.
ptr_parent => ARRAY(0x7f9031838548)
所以我怀疑这样做是不可能的,因为我想象@stuff内存指针会被释放。
我觉得我可以让@root成为$ root,它是指向指针的指针。但我仍然坚持如何写这个。指针的语法仍然不是100%。
但一般要求是,在myfunc中生成的任何列表都需要在@root中生存。我无法直接从myfunc();
修改@root提前致谢。如果我需要澄清,请告诉我。
答案 0 :(得分:3)
在您的代码中,$ptr_parent
是一个包含引用的变量,您正在修改变量,而不是 referent 。如果要修改引用指向的实际内容,则需要使用一些取消引用语法。有关详细信息,请参阅perlreftut;有关所有详细信息,请参阅perlref。
use strict;
use warnings;
use Data::Dump;
my @arr;
dd(\@arr);
foo(\@arr);
dd(\@arr);
bar(\@arr);
dd(\@arr);
sub foo {
my $aref = shift;
@$aref = split(/,/, 'test1,test2,test3'); # notice the dereference
}
sub bar {
my $aref = shift;
$aref->[0] = 42; # individual element dereference
$aref->[1] = 'ponies';
}
输出:
[]
["test1", "test2", "test3"]
[42, "ponies", "test3"]
答案 1 :(得分:2)
Perl通过引用传递,这意味着更改sub中的参数也会在调用者中更改它。但是你没有修改参数($_[0]
);你正在修改一个词法变量($ptr_parent
)。
以下所有内容适用于myfunc($root)
:
# Create the object as needed, and pass it back explicitly on exit.
sub myfunc {
my $parent = $_[0] // [];
push @$parent, split(/,/, 'test1,test2,test3');
$_[0] = $parent;
}
# Create the object, and pass it back explicitly up front.
sub myfunc {
my $parent = shift //= [];
push @$parent, split(/,/, 'test1,test2,test3');
}
# Create the object as needed by using a layer of indirection.
sub myfunc {
my $parent_ref = \shift;
push @{ $$parent_ref }, split(/,/, 'test1,test2,test3');
}
或者你可能不那么“神奇”并传递对myfunc
(myfunc(\$root)
)的引用:
sub myfunc {
my $parent_ref = shift;
push @{ $$parent_ref }, split(/,/, 'test1,test2,test3');
}
顺便说一句,原型是不正确的。我通过删除它解决了这个问题。
答案 2 :(得分:-1)
确实,您需要使用引用,并且如果要从其他位置修改引用,则传递对该引用的引用。
#!/usr/bin/perl
use strict;
my $root = [];
myfunc(\$root);
sub myfunc()
{
my ($ptr_parent) = @_;
print "root => ";
print $root;
print "\n";
print "ptr_parent => $$ptr_parent\n";
my @stuff = split(',', 'test1,test2,test3');
$$ptr_parent = \@stuff;
print "stuff => ";
print \@stuff;
print "\n";
print "root => ";
print $root;
print "\n";
print "ptr_parent => $$ptr_parent\n";
}
输出:
root => ARRAY(0x7f8143001ee8)
ptr_parent => ARRAY(0x7f8143001ee8)
stuff => ARRAY(0x7f8143022ad8)
root => ARRAY(0x7f8143022ad8)
ptr_parent => ARRAY(0x7f8143022ad8)