تاپل‌ها

    یک تاپل (tuple) مجموعه‌ای مرتب و با اندازه ثابت از مقادیری با انواع احتمالی متفاوت است.
    تاپل‌ها سبک‌وزن هستند و برای گروه‌بندی، بازگرداندن یا تجزیه (destructure) چندین مقدار بدون نیاز به تعریف یک struct مفید می‌باشند.

    تاپل‌ها با استفاده از پرانتز نوشته می‌شوند و عناصر با کاما از یکدیگر جدا می‌گردند:

    var t = (10, 20);
    

    می‌توانید با استفاده از اندیس‌های عددی که از 0 شروع می‌شوند به عناصر تاپل دسترسی پیدا کنید:

    printf("%d\n", t.0); // چاپ 10
    printf("%d\n", t.1); // چاپ 20
    

    بازگرداندن تاپل از توابع

    توابع می‌توانند با مشخص کردن یک نوع تاپل به عنوان نوع بازگشتی، چندین مقدار را بازگردانند:

    fn pair(x: int, y: int) (int, int) {
        return (x, y);
    }
    
    pub fn main() {
        var (a, b) = pair(10, 20);
        printf("%d %d\n", a, b);
    }
    

    تجزیه تاپل

    تاپل‌ها را می‌توان در یک عبارت اعلان واحد به متغیرهای مجزا تجزیه (destructure) کرد. هر عنصر در الگوی تاپل، عنصر متناظر خود را از سمت راست دریافت می‌کند.

    pub fn main() {
        var (x, y) = (10, 20);
        printf("%d %d\n", x, y); // چاپ 10 20
    }
    

    تاپل‌های تودرتو

    تاپل‌ها می‌توانند شامل تاپل‌های دیگری باشند. تجزیه به صورت بازگشتی کار می‌کند و با ساختار سمت راست مطابقت دارد:

    pub fn main() {
        var (x, (y, z)) = (1, (2, 3));
        printf("%d %d %d\n", x, y, z); // چاپ 1, 2, 3
    }
    

    این فرم می‌تواند به صورت دلخواه تودرتو باشد و از منطق تجزیه یکسانی برای تمام سطوح پیروی می‌کند.

    انواع تاپل صریح

    می‌توانید انواع تاپل را به‌طور صریح حاشیه‌نویسی کنید تا تجزیه واضح‌تر شود یا محدودیت‌های نوع را اعمال نمایید:

    var (a, (b, c)): (int, (int, char*)) = (10, (20, "Cyrus"));
    
    printf("%d\n", a); // 10
    printf("%d\n", b); // 20
    printf("%s\n", c); // Cyrus
    

    حاشیه‌نویسی‌های نوع اطمینان حاصل می‌کنند که تاپل سمت راست با ساختار اعلان‌شده مطابقت دارد.

    تغییرپذیری

    به طور پیش‌فرض، کلمه کلیدی آغازین (var یا const) برای کل تاپل اعمال می‌شود. با این حال، کوروش به شما امکان می‌دهد تغییرپذیری عناصر خاصی را درون الگو بازنویسی کنید.

    کلمه کلیدی var تمام عناصر تجزیه‌شده را تغییرپذیر می‌کند، در حالی که const همه آنها را تغییرناپذیر می‌سازد:

    const (x, y) = (5, 6); // هر دو x و y تغییرناپذیر هستند
    var (p, q) = (7, 8);   // هر دو p و q تغییرپذیر هستند
    

    تغییرپذیری ترکیبی:

    var (const a, b, c) = (1, 2, 3);
    // a از نوع const (تغییرناپذیر) است
    // b و c از نوع var (تغییرپذیر) هستند
    
    const (a, var b, c) = (1, 2, 3);
    // a و c از نوع const (تغییرناپذیر) هستند
    // b از نوع var (تغییرپذیر) است
    

    حاشیه‌نویسی نوع

    علاوه بر تغییرپذیری ترکیبی، می‌توانید نوع عناصر مجزا را درون یک الگوی تجزیه به‌طور صریح حاشیه‌نویسی کنید. این امر به‌ویژه زمانی مفید است که می‌خواهید یک نوع خاص را اعمال کنید.

    const (var a: int32, (var b: int32, c: int32)) = (1, (2, 3));
    
    // a یک int32 تغییرپذیر است
    // b یک int32 تغییرپذیر است
    // c یک int32 تغییرناپذیر است (const را از ریشه به ارث می‌برد)
    

    محدودیت‌ها

    • تجزیه تاپل فقط در داخل توابع یا حوزه‌های محلی مجاز است.
    • تجزیه بدون سمت راست (مانند var (a, b);) مجاز نیست، زیرا صدور تاپل بدون مقداردهی در کوروش بی‌معناست.

    مثال کد نامعتبر:

    var (a, (b, c)); // صدور تاپل بدون rhs مجاز نیست
    
    • تجزیه تاپل فقط در داخل توابع یا حوزه‌های محلی مجاز است.
    • مقداردهی الزامی است: تجزیه بدون سمت راست (مانند var (a, b);) مجاز نیست.
    • افزونگی کلمه کلیدی: نمی‌توانید کلمه کلیدی تغییرپذیری آغازین را درون الگوی تاپل تکرار کنید. این امر برای حفظ تمیزی دستور زبان، نحوی نامعتبر محسوب می‌شود.
    const (const a, _) = (1, 2); // خطا!: کلمه کلیدی آغازین نمی‌تواند در داخل تکرار شود
    var (var a, _) = (1, 2);     // خطا!: کلمه کلیدی آغازین نمی‌تواند در داخل تکرار شود
    
    var (a, (b, c));             // خطا!