لا يكون لها مفتاح الشباك غير مهيأ قيمة افتراضية صفر في بيرل؟

StackOverflow https://stackoverflow.com/questions/811515

  •  03-07-2019
  •  | 
  •  

سؤال

ولدي كود بيرل مشابهة لما يلي:

# -- start --

my $res;

# run query to fetch IPv6 resources
while( my $row = $org_ip6_res->fetchrow_arrayref )
{
    if( $row->[4] =~ /PA/ ) {
        $res->{ipv6}{pa}{$row->[2]}++;
    } elsif( $row->[4] eq 'PI' ) {
        $res->{ipv6}{pi}{$row->[2]}++;
    }
}

# -- stop --

في أي نقطة من أي وقت مضى $res تعيين قبل بالتكرار عبر نتائج الاستعلام بعد تشغيل التعليمات البرمجية على ما يرام.

وعندما أضع البيانات الطباعة قبل كل قيمة أحصل على الفراغات في كلتا الحالتين ولكن إذا كانت البيانات المطبوعة تأتي بعد تطبيق الزيادة أحصل على قيمة> = 1 اعتمادا على عدد الموارد الإصدار IPv6 لدى المؤسسة.

وسؤالي هو، هل نأخذ هذا يعني مفتاح التجزئة غير مهيأ في بيرل يحتوي على قيمة الصفر تلقائيا؟

وعذرا إذا كان الأمر كما عبر سؤال مبتدئ ولكن أنا فقط لم تكن مألوفة مع هذه التركيبة أي $hashref->{foo}->{bar}++ حيث يحتوي على قيمة لم يتم تعيين صراحة إلى $hashref->{foo}->{bar}. ويرجع الفضل في ذلك مسبقا!

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

المحلول

والقيمة ليست تلقائيا الصفر. كانت القيمة غير محددة في البداية. ومع ذلك، إذا كنت التعامل معها مثل عدد (على سبيل المثال، تطبيق ++ إلى ذلك)، ثم بيرل يعامل وكأنه صفر. إذا كنت التعامل معها مثل سلسلة (على سبيل المثال، تطبيق . إلى ذلك)، ثم بيرل يعامل وكأنه سلسلة فارغة.

ومن perldoc perlsyn، تحت عنوان "الإعلانات":

<اقتباس فقرة>   

والشيء الوحيد الذي يحتاج الى اعلان في   بيرل هي صيغ التقرير و   الوظائف الفرعية (وأحيانا ولا حتى   الوظائف الفرعية). متغير يحمل   قيمة غير محددة ( "نديف") إلى أن لديها   تم تعيين قيمة محددة، والتي   أي شيء آخر غير "نديف". متى   تستخدم عددا "، ونديف" يعامل   كما 0؛ عندما تستخدم على النحو سلسلة، فمن   تعامل على أنها سلسلة فارغة، ""؛ و   عندما تستخدم كمرجع ليست   تم تعيينه ل، يتم التعامل معها على أنها   الخطأ.

نصائح أخرى

لتوضيح آخر تيليماكوس، سيتم غير معرفة القيم غير مهيأ. الأجزاء العميقة للهيكل هي autovivified . هذا هو سمة يدوية حيث يتم إنشاء هياكل البيانات تلقائيا. Autovivification كبيرة عندما تريد ذلك، ولكنه يمكن أن يكون الألم عندما تريد منعها. هناك العديد من الدروس والمقالات والمشاركات في جميع أنحاء الشبكة على فهم autovivification.

وهكذا تتاح له $ref غير معروف و$ref->{ipv6}{pa}{'foo'}++، سيتم تعيين $ref قيمة من:

$ref = { 
     ipv6 => { 
          pa => { 
              foo => undef
          }
     }
};

وبعد ذلك سوف تكون زيادة في نديف، منذ numifies نديف إلى 0، نحصل 0 ++ الذي هو 1. للحصول على نتيجة النهائية: ref->{ipv6}{pa}{'foo'} == 1

إذا كان لديك تحذيرات تمكين، (أنت تفعل use warnings;، أليس كذلك؟) سوف تحصل على تحذير "قيمة غير مهيأ" عندما كنت تعمل على هذه القيم غير محددة. إذا كان هذا هو السلوك المطلوب لزيادة قيمة unitialized، ثم يمكنك تشغيل المجموعة المطلوبة من التحذيرات من أكثر من جزء محدود من التعليمات البرمجية:

use strict;
use warnings;
my $res;

// run query to fetch IPv6 resources
while( my $row = $org_ip6_res->fetchrow_arrayref )
{   no warnings 'uninitialized';
    if( $row->[4] =~ /PA/ ) {
        $res->{ipv6}{pa}{$row->[2]}++;
    } elsif( $row->[4] eq 'PI' ) {
        $res->{ipv6}{pi}{$row->[2]}++;
    }
}

ويمكنك العثور على التسلسل الهرمي تحذيرات في perllexwarn .

وانها غير معروف أساسا، ولكن يعامل كما لو كان الصفر عند زيادة عليه.

وهذا المصطلح في بيرل لغة هو 'autovivified ".

وماذا ربما كنت ترغب في القيام به هو استخدام موجود الكلمة :

$res->{ipv6}{pa}{$row->[2]}++ if exists($res->{ipv6}{pa}{$row->[2]});

وليس هناك شيء مثل التجزئة غير مهيأ <م> مفتاح . الشيء الذي يمكن غير مهيأة هو القيمة <م> للحصول على مفتاح معين. قيمة تجزئة هو مجرد قيمة العددية. انها لا تختلف من متغير مثل $foo.

وهناك زوجين من مختلف بيرل ميزات تتفاعل في المثال الخاص بك.

وغير معرفة في البداية $res (أي أنه لديه undef القيمة). عند استخدام قيمة غير مهيأ كمرجع التجزئة (كما هو الحال في $res->{ipv6}...) بيرل "autovivifies" انها واحدة. وهذا هو، بيرل يخلق التجزئة مجهولة المصدر واستبدال قيمة undef مع إشارة إلى تجزئة جديدة. تكرر هذه العملية (بصمت) في كل مرة تستخدم القيمة الناتجة كمرجع.

وأخيرا، يمكنك autovivify طريقك إلى $res->{ipv6}{pa}{$row->[2]}، وهو غير معروف. تذكر أن هذا هو مجرد قيمة العددية مثل $foo. السلوك هو نفسه قوله

my $foo;
$foo++;

وبيرل يفعل أشياء خاصة عند استخدام قيم غير محددة. اذا كنت استخدامها كرقم، بيرل يحولهم إلى 0. إذا كنت تستخدم لهم كسلسلة، بيرل يحولهم إلى '' (سلسلة فارغة). في معظم الظروف سوف تحصل على "استخدام قيمة غير مهيأ ..." محذرا من انه اذا كان لديك تحذيرات تمكين (والتي يجب). و زيادة تلقائية المشغل (++) هو حالة خاصة، وإن كان. للراحة، وذلك بصمت تحويل القيمة من undef إلى 0 قبل تزايد عليه.

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