برنامه نویسی

HARMONYOS سیستم متغیر بعدی: از تنوع تا مدل حافظه

در توسعه زبان Cangjie در Harmonyos بعدی ، سیستم متغیر پایه و اساس برنامه های ساختمانی است. تنوع ، انواع ارزش و انواع مرجع آن و همچنین استراتژی های مربوط به کامپایلر ، عمیقاً بر منطق در حال اجرا و عملکرد برنامه تأثیر می گذارد. به عنوان یک تکنسین که تجربه عملی غنی را در این زمینه جمع کرده است ، من این نکات کلیدی را بر اساس موارد واقعی تجزیه و تحلیل می کنم.

1. مقایسه/var مقایسه

(i) مزایای متغیرهای تغییر ناپذیر در برنامه نویسی همزمان

به زبان Cangjie ، let برای تعریف متغیرهای تغییر ناپذیر استفاده می شود و var برای تعریف متغیرهای قابل تغییر استفاده می شود. این دو متغیر در سناریوهای برنامه نویسی همزمان تفاوت معنی داری دارند و متغیرهای تغییر ناپذیر مزایای منحصر به فردی را در برنامه نویسی همزمان نشان می دهند.

در یک محیط همزمان ، چندین موضوع ممکن است به طور همزمان به داده های مشترک دسترسی پیدا کرده و اصلاح کنند ، که به راحتی می تواند باعث رقابت داده ها و ناسازگاری شود. به عنوان مثال ، هنگامی که عملیات چند رشته ای روی پیشخوان های مشترک:

// Assume this is in a concurrent environment
var counter = 0
// Thread 1 execution
counter++
// Thread 2 execution
counter++
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

از آنجا که موضوع 1 و موضوع 2 ممکن است مقدار آن را بخوانند و اصلاح کنند counter در عین حال ، ارزش نهایی counter ممکن است مورد انتظار 2 نباشد ، اما 1 (با فرض اینکه موضوع 1 و موضوع 2 مقدار را بخوانید counter 0 است ، سپس 1 را اضافه کنید و دوباره آن را بنویسید ، که اتفاق می افتد).

با استفاده از متغیر تغییر ناپذیر let می تواند به طور موثری از این نوع مشکل جلوگیری کند. از آنجا که یک متغیر تغییر ناپذیر آغاز می شود ، ارزش آن را نمی توان اصلاح کرد ، که خطر رقابت داده ها را از بین می برد. برنامه نویسی همزمان ، ما می توانیم داده های مشترک را به عنوان متغیرهای تغییر ناپذیر تعریف کنیم و سپس با استفاده از برنامه نویسی عملکردی پردازش می کنیم. برای مثال ، هنگام محاسبه نتایج عملیات داده های جدید ، هر یک از داده ها را می توان به عنوان Dataination Dataination در نظر گرفت. Data.in به این روش ، هر موضوع یک کپی داده مستقل را اجرا می کند و با یکدیگر تداخل نخواهد کرد ، بنابراین از سازگاری داده ها و ثبات برنامه اطمینان می دهد.

2. تجزیه و تحلیل عمیق از نوع ارزش/مرجع

(i) تفاوت در رفتار کپی بین ساختار و کلاس (نمودار تخصیص حافظه)

به زبان Cangjie ، struct متعلق به نوع ارزش و class متعلق به نوع مرجع است. تفاوتهای آشکاری در رفتار کپی آنها وجود دارد ، که از نزدیک با روش تخصیص حافظه ارتباط دارد.

برای نوع ارزش struct، یک نسخه جدید هنگام انجام تکالیف ایجاد می شود. برای مثال:

struct Point {
    var x: Int
    var y: Int
}

main() {
    let p1 = Point(x: 1, y: 2)
    var p2 = p1
    p2.x = 3
    println("p1.x: \(p1.x), p2.x: \(p2.x)")
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در کد فوق ، چه زمانی p2 = p1با p2 یک نسخه از p1، اصلاح p2.x تأثیر نخواهد گذاشت p1.x، و نتیجه خروجی “p1.x: 1 ، p2.x: 3” است. از دیدگاه تخصیص حافظه ، p1 وت p2 فضای حافظه مستقل خود را در پشته قرار دهید و همان مقدار داده را ذخیره کنید ، همانطور که در زیر آمده است:

graph TD;
A[stack memory] --> B[p1(x:1,y:2)];
A --> C[p2(x:1,y:2)];
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برای نوع مرجع class، عملیات واگذاری فقط یک رابطه مرجع ایجاد می کند. برای مثال:

class Point {
    var x: Int
    var y: Int

    init(x: Int, y: Int) {
        this.x = x
        this.y = y
    }
}

main() {
    let p1 = Point(x: 1, y: 2)
    let p2 = p1
    p2.x = 3
    println("p1.x: \(p1.x), p2.x: \(p2.x)")
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اینجا ، بعد از p2 = p1با p1 وت p2 در حافظه پشته به همان شیء اشاره کنید. اصلاح کننده p2.x تأثیر خواهد گذاشت p1.x، و نتیجه خروجی “p1.x: 3 ، p2.x: 3” است. وضعیت تخصیص حافظه به شرح زیر است:

graph TD;
A[stack memory] --> B[p1 (points to objects in heap memory)];
A --> C[p2 (points to the same object in heap memory)];
D[heap memory] --> E[object(x:1,y:2, then becomes x:3,y:2)];
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

درک این تفاوت در رفتار کپی برای نوشتن کد مناسب ضروری است. در توسعه واقعی ، در صورت نیاز به یک کپی داده مستقل ، نوع ارزش باید انتخاب شود. اگر می خواهید داده ها را به اشتراک بگذارید و استفاده از حافظه را بهبود بخشید ، باید نوع مرجع انتخاب شود.

3. استراتژی محافظه کارانه کامپایلر

(i) اصل گزارش خطای اولیه سازی متغیر در بلوک آزمایشی

به زبان Cangjie ، کامپایلر یک استراتژی محافظه کارانه را برای اداره اولیه سازی متغیر اتخاذ می کند ، که به ویژه در آن آشکار است try-catch block. برای مثال:

main() {
    let a: String
    try {
        a = "1"
    } catch (_) {
        a = "2" // Error, cannot assign to immutable value
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

کد فوق خطایی را گزارش می کند زیرا کامپایلر فرض می کند که همه try بلوک ها همیشه اجرا می شوند و استثنائات همیشه پرتاب می شوند. a ممکن است وارد شود catch بلوک بدون ابتدای کار در try بلوک ، و متغیر تغییر ناپذیر a نمی توان چندین بار اختصاص یافت ، بنابراین کامپایلر خطایی را گزارش می کند.

از دیدگاه کامپایلر ، این استراتژی محافظه کارانه اطمینان از امنیت و ثبات Code.in منطق برنامه پیچیده ، کد در try بلوک ممکن است شامل عملیات مختلفی باشد که ممکن است استثنائات را به وجود آورد ، و کامپایلر نمی تواند تعیین کند که آیا متغیرهای موجود در آن try بلوک آغاز می شود. بنابراین ، برای جلوگیری از خطاهای احتمالی زمان اجرا ، کامپایلر یک استراتژی محافظه کارانه را برای گزارش یک پیام خطا به این وضعیت اتخاذ می کند. در توسعه واقعی ، ما باید به رفتار کامپایلر توجه کنیم و به طور منطقی به طور منطقی رفتار کنیم ، مانند اولیه سازی متغیرهای خارج از متغیرهای خارج از try-catch بلوک ، یا تنظیم ساختار کد را با توجه به منطق خاص برای برآورده کردن نیازهای کامپایلر و اطمینان از اینکه برنامه می تواند به درستی تهیه و اجرا شود.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا