سؤال

لقد صادفت السطر التالي من التعليمات البرمجية.لديها قضايا:

  • الغرض منه هو أن تفعل نفس الشيء مثل الدفع
  • كان ينبغي أن تستخدم الدفع
  • من الصعب القراءة والفهم
  • لقد قمت منذ ذلك الحين بتغييره لاستخدام الدفع
  • إنه يفعل شيئًا اعتقدت أنه غير قانوني، لكن من الواضح أنه ليس كذلك

ها هو:

$array [++$#array] = 'data';

سؤالي هو:ماذا يعني الزيادة المسبقة $#array؟لقد اعتبرت دائمًا $#array إحدى سمات المصفوفة وغير قابلة للكتابة.

هل كانت مفيدة؟

المحلول

com.perldata يقول:

"طول المصفوفة هو قيمة عددية.يمكنك العثور على طول المصفوفة @days من خلال تقييم $#days ، كما في csh.ومع ذلك، هذا ليس طول المصفوفة؛إنه منخفض للعنصر الأخير، وهي قيمة مختلفة نظرًا لوجود عنصر 0 عادةً.يؤدي تعيين $#days فعليًا إلى تغيير طول المصفوفة.يؤدي تقصير المصفوفة بهذه الطريقة إلى تدمير القيم المتداخلة.إن إطالة مصفوفة تم تقصيرها مسبقًا لا يؤدي إلى استعادة القيم الموجودة في تلك العناصر."

يعد تعديل $#array مفيدًا في بعض الحالات، ولكن في هذه الحالة، من الواضح أن الدفع هو الأفضل.

نصائح أخرى

ستعيد الزيادة اللاحقة المتغير أولاً ثم تزيده.

إذا استخدمت الزيادة اللاحقة، فستقوم بتعديل العنصر الأخير، لأنه تم إرجاعه أولاً، ثم دفع عنصر فارغ إلى النهاية.في الحلقة الثانية، ستقوم بتعديل تلك القيمة الفارغة ودفع قيمة فارغة جديدة لوقت لاحق.لذلك لن تعمل مثل الدفع على الإطلاق.

الزيادة المسبقة ستزيد المتغير ثم تعيده.بهذه الطريقة، سيتم كتابة المثال الخاص بك دائمًا إلى العنصر الأخير الجديد في المصفوفة وسيعمل مثل الدفع.المثال أدناه:

my (@pre, @post);

$pre[$#pre++] = '1';
$pre[$#pre++] = '2';
$pre[$#pre++] = '3';


$post[++$#post] = '1';
$post[++$#post] = '2';
$post[++$#post] = '3';

print "pre keys: ".@pre."\n";
print "pre: @pre\n";
print "post keys: ".@post."\n";
print "post: @post\n";

المخرجات:

pre keys: 3
pre: 2 3
post keys: 3
post: 1 2 3

تعيين قيمة أكبر من طول الصفيف الحالي $#array يمتد المصفوفة.

يعمل هذا الكود أيضًا:

$ perl -le 'my @a; $a[@a]="Hello"; $a[@a]=" world!"; print @a'
Hello world!

مصفوفة Perl ديناميكية وتنمو عند تعيينها خارج الحدود.

بادئ ذي بدء، هذا خطأ.

ومع ذلك، أنا مندهش أيضًا من نجاحه.كنت قد خمنت ذلك ++$#array كان من الممكن أن تحصل على الخطأ "لا يمكن تعديل الثابت" الذي تحصل عليه عند محاولة زيادة رقم.(لا يعني ذلك أنني أفعل ذلك عن طريق الخطأ بالطبع). ولكن أعتقد أن هذا هو بالضبط ما كنا مخطئين فيه: $#array ليس ثابتًا (رقمًا)؛إنه تعبير متغير.على هذا النحو يمكنك الفوضى معها.خذ بعين الاعتبار ما يلي:

my @array = qw/1 2 3/;

++$#array;
$array[$#array] = qw/4/;

print "@array\n"

وحتى لمزيد من المتعة، هذا:

my @array = qw/1 2 3/;

$#array += 5;

foreach my $wtf (@array) {
  if (defined $wtf) {
    print "$wtf\n";
  }
  else {
    print "undef\n";
  }
}

و نعم كتاب الطبخ بيرل سعيد بالعبث معه $#array لتنمية المصفوفات أو اقتطاعها (الفصل 4، الوصفة 3).ما زلت أجده قبيحًا، ولكن ربما يكون هذا مجرد تحيز طويل الأمد "لكنه رقم".

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top