برنامه نویسی

Mastering Go Clices: شیرجه عمیق از صفر به قهرمان

برش های Go سنگ بنای زبان است و یک روش انعطاف پذیر برای کار با توالی داده ها ارائه می دهد. آنها آرایه نیستند ، اما در بالای آنها ساخته شده اند و درک می کنند که چگونه آنها در زیر کاپوت کار می کنند می توانند برنامه نویسی GO شما را بالا ببرند. این پست برش هایی را از اصول اولیه به موارد پیشرفته استفاده می کند ، با نمونه های واضح و نکات عملی. بیایید شیرجه بزنیم.

برش ها چیست؟

یک برش در GO است ساختار سبک وزن این یک پنجره را به یک آرایه زیرین فراهم می کند. بر خلاف آرایه ها ، که دارای طول ثابت هستند ، برش ها پویا هستند ، به این معنی که می توانید آنها را رشد داده یا کوچک کنید (در محدوده). یک برش توسط سه مؤلفه تعریف شده است: الف اشاره کننده به آرایه ، الف طول (تعداد عناصر در دسترس) ، و الف ظرفیت (کل عناصر موجود در آرایه اساسی).

در اینجا یک مثال ساده برای نشان دادن یک برش در عمل وجود دارد:

package main

import "fmt"

func main() {
    // Create a slice directly
    numbers := []int{1, 2, 3, 4, 5}
    fmt.Println("Slice:", numbers)
    fmt.Println("Length:", len(numbers))
    fmt.Println("Capacity:", cap(numbers))
}

// Output:
// Slice: [1 2 3 4 5]
// Length: 5
// Capacity: 5
حالت تمام صفحه را وارد کنید

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

برش ها با اعلام می شوند []type، و می توانید آنها را با استفاده از تحت اللفظی (مانند بالا) یا موارد ایجاد کنید make عملکرد. اگر می خواهید اطلاعات بیشتری داشته باشید ، وبلاگ Go دارای شیرجه عمیق بسیار خوبی در قسمت داخلی برش است.

ایجاد برش: روشهای زیادی

شما می توانید برش هایی را از چند طریق ایجاد کنید که هر کدام مورد استفاده خود را دارند. در اینجا یک شکست:

روش نحو چه زمانی استفاده کنید
لفظی s := []int{1, 2, 3} تنظیم سریع با مقادیر شناخته شده
make s := make([]int, len, cap) طول و ظرفیت قبل از اختصاص
از آرایه s := arr[start:end] با بخشی از یک آرایه موجود کار کنید
نیل برش var s []int یک برش خالی را آغاز کنید (بدون تخصیص)

در اینجا یک مثال کامل نشان داده شده است که روشهای مختلف آفرینش را نشان می دهد:

package main

import "fmt"

func main() {
    // Slice literal
    literal := []int{10, 20, 30}
    fmt.Println("Literal slice:", literal)

    // Using make
    made := make([]int, 2, 5)
    made[0], made[1] = 1, 2
    fmt.Println("Made slice:", made, "Len:", len(made), "Cap:", cap(made))

    // From array
    array := [5]int{100, 200, 300, 400, 500}
    fromArray := array[1:4]
    fmt.Println("From array:", fromArray)

    // Nil slice
    var nilSlice []int
    fmt.Println("Nil slice:", nilSlice, "Is nil?", nilSlice == nil)
}

// Output:
// Literal slice: [10 20 30]
// Made slice: [1 2] Len: 2 Cap: 5
// From array: [200 300 400]
// Nil slice: [] Is nil? true
حالت تمام صفحه را وارد کنید

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

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

برش نحو: برش آرایه ها مانند یک حرفه ای

نحو برش s[start:end] به شما امکان می دهد یک برش جدید از یک آرایه یا یک برش دیگر ایجاد کنید. در start فهرست فراگیر است ، و end منحصر به فرد است همچنین می توانید از فهرست سوم استفاده کنید ، s[start:end:max]، برای کنترل ظرفیت.

در اینجا یک مثال آورده شده است:

package main

import "fmt"

func main() {
    array := [6]int{0, 1, 2, 3, 4, 5}

    // Basic slicing
    s1 := array[1:4]
    fmt.Println("s1:", s1, "Len:", len(s1), "Cap:", cap(s1))

    // Slice with max capacity
    s2 := array[1:4:5]
    fmt.Println("s2:", s2, "Len:", len(s2), "Cap:", cap(s2))

    // Full slice
    s3 := array[:]
    fmt.Println("s3:", s3, "Len:", len(s3), "Cap:", cap(s3))
}

// Output:
// s1: [1 2 3] Len: 3 Cap: 5
// s2: [1 2 3] Len: 3 Cap: 4
// s3: [0 1 2 3 4 5] Len: 6 Cap: 6
حالت تمام صفحه را وارد کنید

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

نکته اصلی: ظرفیت یک برش با طول آرایه زیرین از start فهرست به پایان آرایه یا max فهرست

افزودن به برش ها: در حال رشد با append

در append عملکرد نحوه اضافه کردن عناصر به یک برش است. اگر آرایه زیرین ظرفیت کافی داشته باشد ، append از آن استفاده می کند در غیر این صورت ، GO یک آرایه جدید و بزرگتر را اختصاص می دهد. این می تواند بر عملکرد تأثیر بگذارد ، بنابراین از قبل با make اغلب برای برش های بزرگ بهتر است.

مثال:

package main

import "fmt"

func main() {
    s := []int{1, 2}
    fmt.Println("Before:", s, "Len:", len(s), "Cap:", cap(s))

    // Append one element
    s = append(s, 3)
    fmt.Println("After one:", s, "Len:", len(s), "Cap:", cap(s))

    // Append multiple elements
    s = append(s, 4, 5, 6)
    fmt.Println("After many:", s, "Len:", len(s), "Cap:", cap(s))
}

// Output:
// Before: [1 2] Len: 2 Cap: 2
// After one: [1 2 3] Len: 3 Cap: 4
// After many: [1 2 3 4 5 6] Len: 6 Cap: 8
حالت تمام صفحه را وارد کنید

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

توجه کنید که چگونه ظرفیت (2 → 4 → 8) در هنگام رشد برش دو برابر می شود. مشخصات GO این رفتار را توضیح می دهد.

نکته اصلی: همیشه نتیجه را اختصاص دهید append بازگشت به برش ، زیرا ممکن است یک قطعه جدید را برگرداند.

کپی برش ها: جلوگیری از مشکلات مشترک داده ها

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

در اینجا مثالی وجود دارد که تفاوت را نشان می دهد:

package main

import "fmt"

func main() {
    src := []int{1, 2, 3, 4}
    dst := make([]int, 2)

    // Copy first two elements
    n := copy(dst, src)
    fmt.Println("Copied:", dst, "Elements copied:", n)

    // Modify source
    src[0] = 99
    fmt.Println("Source after mod:", src)
    fmt.Println("Dest after mod:", dst)
}

// Output:
// Copied: [1 2] Elements copied: 2
// Source after mod: [99 2 3 4]
// Dest after mod: [1 2]
حالت تمام صفحه را وارد کنید

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

نکته اصلی: استفاده کنید copy هنگامی که برای جلوگیری از تغییر داده های اصلی به یک قطعه مستقل نیاز دارید.

slice gotchas: اشتباهات رایج برای جلوگیری از

برش ها قدرتمند هستند اما می توانند به شما سفر کنند. در اینجا مشکلات مشترک وجود دارد:

اشتباه مشکل ثابت کردن
اصلاح آرایه های مشترک تغییرات در یک برش بر دیگران تأثیر می گذارد استفاده کردن copy یا یک برش جدید ایجاد کنید
وحشت نیل دسترسی به عناصر در یک قطعه صفر بررسی کردن nil یا اولیه کردن
خارج از مرز دسترسی به فراتر از طول استفاده کردن len برای بررسی مرزها

نمونه ای از مسئله آرایه مشترک:

package main

import "fmt"

func main() {
    array := [4]int{1, 2, 3, 4}
    s1 := array[:2]
    s2 := array[1:3]

    s1[1] = 99
    fmt.Println("s1:", s1)
    fmt.Println("s2:", s2) // s2 is affected!
}

// Output:
// s1: [1 99]
// s2: [99 3]
حالت تمام صفحه را وارد کنید

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

نکته اصلی: همیشه هنگام کار با چندین برش از آرایه زیرین آگاه باشید.

نکات عملکرد: کارآمد ساختن برش

برش ها سریع هستند ، اما سوء استفاده می تواند برنامه شما را کند کند. در اینجا نکاتی برای بهینه سازی وجود دارد:

  • پیش اختصاص با make: طول و ظرفیت را برای جلوگیری از بازگرداندن تنظیم کنید.
  • به حداقل رساندن append فراخوانی: دسته ای برای کاهش کپی کردن آرایه.
  • استفاده کردن copy عاقلانه: فقط آنچه را که برای جلوگیری از سربار غیر ضروری لازم دارید کپی کنید.

نمونه ای از پیشگیری در مقابل رشد پویا:

package main

import "fmt"

func main() {
    // Pre-allocated
    s1 := make([]int, 0, 100)
    for i := 0; i < 100; i++ {
        s1 = append(s1, i)
    }
    fmt.Println("Pre-allocated len:", len(s1), "cap:", cap(s1))

    // Dynamic growth
    s2 := []int{}
    for i := 0; i < 100; i++ {
        s2 = append(s2, i)
    }
    fmt.Println("Dynamic len:", len(s2), "cap:", cap(s2))
}

// Output:
// Pre-allocated len: 100 cap: 100
// Dynamic len: 100 cap: 128
حالت تمام صفحه را وارد کنید

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

نکته اصلی: قبل از تخصیص ، تخصیص حافظه را کاهش داده و عملکرد را بهبود می بخشد.

الگوهای برش عملی: در دنیای واقعی استفاده می کند

برش ها در سناریوهای دنیای واقعی می درخشند. در اینجا دو الگوی مشترک وجود دارد:

  1. تصفیه: یک برش جدید با عناصر مطابق با یک شرط ایجاد کنید.
  2. چاک دهی: یک برش را به برش های کوچکتر تقسیم کنید.

مثال فیلتر:

package main

import "fmt"

func main() {
    numbers := []int{1, 2, 3, 4, 5, 6}
    evens := []int{}

    for _, n := range numbers {
        if n%2 == 0 {
            evens = append(evens, n)
        }
    }

    fmt.Println("Evens:", evens)
}

// Output:
// Evens: [2 4 6]
حالت تمام صفحه را وارد کنید

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

برای جمع آوری یا الگوهای دیگر ، راهنمای GO موثر را بررسی کنید.

با برش ها به کجا بروید

برش ها یک بخش اساسی از GO هستند و تسلط بر آنها کدگذاری کارآمد و اصطلاحات را باز می کند. برای تعمیق درک خود ، این مراحل را امتحان کنید:

  • آزمایش: برای آزمایش رفتار برش ، مانند تغییر اندازه یا به اشتراک گذاری آرایه ها ، برنامه های کوچک بنویسید.
  • منبع را بخوانید: اجرای برش Go Runtime (در runtime/slice.go) نشان می دهد که چگونه append و کار رشد
  • کد خود را مشخص کنید: از Go استفاده کنید pprof ابزاری برای نشان دادن مسائل مربوط به عملکرد مربوط به برش.
  • کتابخانه ها را کاوش کنید: نگاه کنید که بسته ها چگونه هستند sort یا container از برش ها استفاده کنید.

برش ها ممکن است ساده به نظر برسند ، اما انعطاف پذیری و عملکرد آنها باعث می شود که آنها در ابزار ابزار توسعه دهنده GO به ابزاری قدرتمند تبدیل شوند. تمرین خود را ادامه دهید ، و مانند یک حرفه ای خرد خواهید شد.

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

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

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

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