تغییرات جدید گولنگ 1.23

ورژن 1.23 گولنگ حدودا بعد از 6 ماه از نسخه قبلی یعنی 1.22 منتشر شد. در این تغییرات بیشتر روی runtime، library و toolchain اعمال شده. در این پست ما تمامی تغییرات این نسخه باهم بررسی میکنیم.

 

تبدیل شدن قابلیت "range-over-func" به بخشی از زبان:

در نسخه 1.22، قابلیتی به صورت آزمایشی معرفی شده بود که اجازه می‌داد از یک تابع به عنوان یک منبع برای حلقه‌های for-range استفاده شود. این قابلیت اکنون به طور رسمی بخشی از زبان Go شده است.

این تغییر به این معناست که در نسخه 1.23، می‌توانید از توابعی با امضای زیر در بخش range یک حلقه for-range استفاده کنید:

func(func() bool)

func(func(K) bool)

func(func(K, V) bool)

این توابع iterator (تکرارکننده) هستند و هر بار که تابع آرگومان فراخوانی می‌شود، مقادیر تکرار را برای حلقه for-range تولید می‌کنند: 

import "fmt"

// تابع iterator که یک عدد از 1 تا 3 را برمی‌گرداند.
func iter(next func(int) bool) {
    for i := 1; i <= 3; i++ {
       if !next(i) {
          break
       }
    }
}

func main() {
    // استفاده از تابع iter در یک حلقه for-range
    for i := range iter {
       fmt.Println(i)
    }
}
 

پشتیبانی اولیه از "generic type alias":

این ویژگی به شما امکان می‌دهد که از نام‌های مستعار (alias) برای انواع ژنریک استفاده کنید.

import "fmt"

type Pair[T any] struct {
    first, second T
}

type IntPair = Pair[int]

func main() {
    p := IntPair{first: 1, second: 2}
    fmt.Println(p)
}

در این مثال، IntPair یک "alias" برای نوع ژنریک Pair است که از نوع int استفاده می‌کند.

 

بهبود در پاکسازی حافظه و "Garbage Collection":

در Go 1.23، عملکرد Garbage Collector بهبود یافته است و تخصیص حافظه نیز کارآمدتر شده است.

برای مشاهده این بهبودها نیاز به یک برنامه خاص نیست، بلکه این بهبودها به صورت داخلی و بدون تغییر در کدهای موجود اعمال می‌شوند.

 

بهبود ابزارهای توسعه مانند go vet و go test:

در این نسخه، ابزارهای go vet و go test بهینه‌سازی‌هایی داشته‌اند که باعث تشخیص بهتر خطاها و بهبود عملکرد تست‌ها می‌شود.

در هنگام استفاده از go vet، اگر کدی داشته باشید که برخی اصول بهترین روش‌ها را نقض می‌کند، ابزار به شما هشدار می‌دهد. برای مثال، go vet می‌تواند متغیرهای تعریف‌شده اما استفاده‌نشده را گزارش کند.

 

بهبود در زمان اجرای برنامه‌ها (Runtime):

در Go 1.23، برخی بهبودها در زمان اجرای برنامه (Runtime) اعمال شده که باعث کاهش مصرف حافظه و افزایش کارایی می‌شود.

 

بهبود Trace

این تغییر در ابزار trace بهبود قابل توجهی در مدیریت داده‌های ناقص و خراب در ردیابی‌های (traces) برنامه‌ها ایجاد کرده است. ابزار trace در Go برای جمع‌آوری و مشاهده داده‌های عملکرد (performance) و اجرای برنامه‌ها استفاده می‌شود. این ابزار به توسعه‌دهندگان کمک می‌کند تا مشکلات کارایی و رفتارهای غیرمنتظره برنامه‌ها را شناسایی و تحلیل کنند.

 

اضافه شدن فلگ -ldflags به Cgo

این تغییر در ابزار cgo (که به توسعه‌دهندگان Go اجازه می‌دهد تا کدهای Go را با زبان C ترکیب کنند) اضافه شدن پشتیبانی از یک فلگ جدید به نام -ldflags را توضیح می‌دهد. این فلگ برای انتقال فلگ‌ها به لینک‌کننده‌ی زبان C استفاده می‌شود.

 

Linker

 

این تغییرات مربوط به لینک‌کننده (Linker) در Go 1.23 شامل سه بخش مهم هستند:

1. محدودیت‌های جدید برای دستور //go:linkname:

  • //go:linkname چیست؟
    دستور //go:linkname یک ابزار قدرتمند در Go است که به برنامه‌نویسان اجازه می‌دهد تا یک نام تابع یا متغیر در یک بسته را به نام دیگری در یک بسته دیگر متصل کنند. این ابزار معمولاً برای دسترسی به نمادهای داخلی (internal symbols) استفاده می‌شود که در حالت عادی برای بسته‌های دیگر قابل دسترسی نیستند.

  • تغییرات جدید:
    در Go 1.23، استفاده از //go:linkname برای ارجاع به نمادهای داخلی در کتابخانه استاندارد (از جمله runtime) که در تعریف خودشان با //go:linkname مشخص نشده‌اند، ممنوع شده است. همچنین، استفاده از این نمادها در کد اسمبلی نیز مجاز نیست.

  • دلایل این محدودیت:
    این تغییر به منظور افزایش امنیت و پایداری کد اعمال شده است. استفاده غیرمجاز از //go:linkname می‌تواند منجر به رفتارهای غیرمنتظره و خطاهای پیچیده در برنامه‌ها شود.

  • سازگاری:
    برای حفظ سازگاری با نسخه‌های قبلی، استفاده‌های فعلی از //go:linkname که در پروژه‌های منبع باز بزرگ وجود دارد، همچنان پشتیبانی می‌شوند. اما هرگونه استفاده جدید از این دستور برای ارجاع به نمادهای داخلی کتابخانه استاندارد ممنوع خواهد بود.

  • فلگ -checklinkname=0:
    اگر به دلایل دیباگینگ یا آزمایش نیاز دارید این محدودیت را غیرفعال کنید، می‌توانید از فلگ -checklinkname=0 استفاده کنید. این فلگ بررسی این محدودیت را غیرفعال می‌کند، اما این کار فقط برای اهداف خاص توصیه می‌شود.

2. فلگ جدید -bindnow برای باینری‌های ELF:

  • باینری‌های ELF و PIE:
    ELF (Executable and Linkable Format) یک فرمت استاندارد برای فایل‌های اجرایی در سیستم‌های یونیکس و لینوکس است. PIE (Position Independent Executable) نوعی باینری است که به طور خاص برای افزایش امنیت و انعطاف‌پذیری طراحی شده است و می‌تواند در هر مکان از حافظه اجرا شود.

  • فلگ -bindnow:
    این فلگ جدید، پیونددهی فوری توابع را فعال می‌کند. به طور معمول، توابع در باینری‌های ELF به صورت تأخیری (lazy) لینک می‌شوند، یعنی فقط زمانی که اولین بار فراخوانی می‌شوند، لینک می‌شوند. اما با فعال‌سازی -bindnow، تمام توابع بلافاصله در زمان بارگذاری باینری لینک می‌شوند.

  • مزایا:
    استفاده از -bindnow می‌تواند مزایایی از جمله کاهش ریسک برخی حملات امنیتی (مانند حملات بر اساس تأخیر در پیونددهی) و بهبود پایداری در برنامه‌هایی که در محیط‌های خاص اجرا می‌شوند، داشته باشد.

 

تغییرات پکیج های استاندارد (Standard Library):

تغییرات Go 1.23 در بخش‌های مختلف کتابخانه استاندارد شامل چندین بهبود و افزودن امکانات جدید می‌باشد. در زیر برخی از این تغییرات همراه با توضیح و مثال آورده شده است:

1. تغییرات در time.Timer و time.Ticker:

رفتار جدید تایمرها و تیکرها:

در Go 1.23، تایمرها و تیکرهایی که دیگر توسط برنامه ارجاع داده نمی‌شوند، بلافاصله برای جمع‌آوری زباله (garbage collection) واجد شرایط می‌شوند، حتی اگر متد Stop آن‌ها فراخوانی نشده باشد. در نسخه‌های قبلی، تایمرهای متوقف نشده تا بعد از اینکه فعال می‌شدند جمع‌آوری نمی‌شدند و تیکرهای متوقف نشده هرگز جمع‌آوری نمی‌شدند.

تغییر در کانال‌های تایمر و تیکر:

کانال‌های تایمرها و تیکرها اکنون بدون بافر (unbuffered) هستند، با ظرفیت 0. این تغییر باعث می‌شود که برای هر فراخوانی به متدهای Reset یا Stop، هیچ مقدار قدیمی‌ای که قبل از آن فراخوانی آماده شده بود، بعد از آن فراخوانی ارسال یا دریافت نشود. در نسخه‌های قبلی، کانال‌ها با یک بافر یک‌عنصری بودند که استفاده صحیح از Reset و Stop را دشوار می‌کرد.

import (
    "fmt"
    "time"
)

func main() {
    timer := time.NewTimer(2 * time.Second)
    fmt.Println("Timer started")

    go func() {
       <-timer.C
       fmt.Println("Timer fired")
    }()

    time.Sleep(1 * time.Second)
    timer.Stop()
    fmt.Println("Timer stopped")
}
  • در این مثال، تایمر پس از 2 ثانیه فعال می‌شود، اما متد Stop آن قبل از اینکه تایمر فعال شود، فراخوانی می‌شود. در نسخه‌های قبلی Go، ممکن بود مقدار تایمر پس از Stop ارسال شود، اما در Go 1.23، این امکان وجود ندارد.

2. بسته‌ی جدید unique:

امکانات جدید برای "canonicalization":

بسته‌ی unique جدیدی اضافه شده که امکاناتی برای "canonicalizing" مقادیر ارائه می‌دهد. این امکان به برنامه‌نویسان اجازه می‌دهد تا مقادیر مشابه را به صورت کارآمدتر ذخیره کنند و از این طریق مصرف حافظه را کاهش دهند.

import (
    "fmt"
    "golang.org/x/exp/unique"
)

func main() {
    handle1 := unique.Make("Hello")
    handle2 := unique.Make("Hello")
    fmt.Println(handle1 == handle2) // true
}

در این مثال، مقدار "Hello" تنها یک‌بار ذخیره می‌شود و هر دو handle به یک مقدار اشاره دارند.

3. بسته‌ی جدید iter:

تعریف‌های پایه برای کار با "iterators":

بسته‌ی iter تعریف‌های پایه‌ای برای کار با "iterators" ارائه می‌دهد. این امکانات شامل توابعی برای ایجاد و مدیریت "iterators" است که می‌توانند روی آرایه‌ها و مپ‌ها اعمال شوند.

import (
    "fmt"
    "golang.org/x/exp/iter"
    "golang.org/x/exp/slices"
)

func main() {
    s := []int{1, 2, 3, 4, 5}
    it := slices.Iter(s)
    for it.Next() {
       fmt.Println(it.Value())
    }
}

در این مثال، از بسته‌ی iter برای ایجاد یک "iterator" روی آرایه استفاده شده است.

4. تغییرات در crypto/tls:

پشتیبانی از Encrypted Client Hello (ECH):

در Go 1.23، مشتری TLS از پیش‌نویس مشخصات Encrypted Client Hello (ECH) پشتیبانی می‌کند. این ویژگی با تنظیم فیلد Config.EncryptedClientHelloConfigList فعال می‌شود.

مثال: این تغییر به طور خاص در پیاده‌سازی‌های TLS پیشرفته کاربرد دارد و معمولاً نیاز به تنظیمات پیچیده‌تری در سطح کد TLS دارد.

5. بسته‌ی جدید structs:

انواع ساختارهای اصلاح‌کننده:

بسته‌ی structs جدیدی اضافه شده که انواعی برای فیلدهای ساختار فراهم می‌کند که ویژگی‌های نوع ساختار را تغییر می‌دهند. به عنوان مثال، HostLayout تضمین می‌کند که ساختار با انتظارات پلتفرم میزبان هماهنگ است.

مثال: این بسته برای کدهای سطح پایین و ارتباط با APIهای سیستم‌عامل میزبان کاربرد دارد.

این توضیحات و مثال‌ها برخی از مهم‌ترین تغییرات Go 1.23 را پوشش می‌دهند. این نسخه شامل بهبودهای زیادی در زمینه امنیت، کارایی و قابلیت استفاده از ابزارها و کتابخانه‌ها می‌باشد.

 

امیدوارم خوشتون اومده باشه💜

0 🔥
0 🎉
0 😮
0 👍
0 💜
0 👏
میلاد خسروی
نویسنده کد نیوز

برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁