برنامه نویسی

Go Pointers در مقابل ارزش ها: چه موقع از آنها استفاده کنید (و چه موقع نیست)

اگر تازه وارد شوید ، یک مورد که به سرعت متوجه خواهید شد این است که Go ندارد null مانند برخی از زبانهای دیگر – این دارد مقادیر صفر در عوض اما اگر شما نیاز به تفاوت بین زمینه ای که هرگز تنظیم نشده است و یکی از مواردی که صریحاً روی صفر تنظیم شده است ، چه می کنید؟ اینجاست نشانگرها می تواند کمک کند – اما آنها همچنین می توانند پیچیدگی غیر ضروری را معرفی کنند. بیایید قدم به قدم آن را بشکنیم.

مشکل: از دست رفته در مقابل صفر

تصور کنید که با داده های JSON کار می کنید که نمایانگر یک کاربر است:

{ "name": "" }
حالت تمام صفحه را وارد کنید

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

در مقابل

{}
حالت تمام صفحه را وارد کنید

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

اگر ساختار GO خود را مانند این تعریف کنیم:

type User struct {  
    Name string `json:"name"`  
}
حالت تمام صفحه را وارد کنید

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

هر دو نمونه JSON در بالا منجر به user.Name == "" در برو این بدان معنی است که ما نمی توانیم بگوییم که آیا این نام وجود دارد:

  1. عمداً تنظیم شده است به یک رشته خالی
  2. هرگز شامل نمی شود اصلاً در JSON.

اگر مقادیر از دست رفته نیاز به دست زدن به ویژه داشته باشند ، این می تواند یک مشکل باشد.

راه حل: استفاده از نشانگرها برای JSON

type User struct {  
    Name *string `json:"name"`  
}
حالت تمام صفحه را وارد کنید

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

اکنون ، ما می توانیم بررسی کنیم که آیا Name است ، nil:

func main() {
    jsonData := `{}`  // No "name" field

    var user User
    json.Unmarshal([]byte(jsonData), &user)

    if user.Name == nil {
        fmt.Println("Name is missing")
    } else {
        fmt.Println("Name is:", *user.Name)
    }
}
حالت تمام صفحه را وارد کنید

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

اینجا چه اتفاقی می افتد؟

  • اگر name زمینه در JSON وجود ندارد ، user.Name == nilبشر

  • اگر name زمینه وجود دارد اما خالی است ("name": "") user.Name است ، نه صفر، اما مقدار آن است ""بشر

این کار هنگام کار با API ، پایگاه داده یا تنظیماتی که در آن مقدار از دست رفته با یک خالی متفاوت است ، مفید است.

هنگام استفاده از نشانگرها

نشانگرها می توانند باشند بیش از حد، خواندن کد سخت تر و مستعد خطا.

مثال: تنظیمات پیکربندی

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

type Config struct {  
    Timeout *int  
}
حالت تمام صفحه را وارد کنید

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

اکنون ، هر بار که می خواهیم از آن استفاده کنیم ، باید بررسی کنیم که آیا این است nil:

if config.Timeout != nil {
    fmt.Println("Timeout is set to:", *config.Timeout)
} else {
    fmt.Println("No timeout set")
}
حالت تمام صفحه را وارد کنید

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

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

type Config struct {  
    Timeout int  
    IsSet   bool  
}
حالت تمام صفحه را وارد کنید

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

اکنون ، ما بررسی می کنیم که آیا IsSet درست است:

if config.IsSet {
    fmt.Println("Timeout is set to:", config.Timeout)
} else {
    fmt.Println("No timeout set")
}
حالت تمام صفحه را وارد کنید

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

چرا این بهتر است؟

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

پیشخدمت

  • از نشانگرها استفاده کنید هنگامی که شما نیاز به تمایز بین “UNSET” و “ZERO VALE” (به خصوص در JSON و API) دارید.

  • از انواع ارزش استفاده کنید هنگامی که یک مقدار صفر کافی است و نیازی به ردیابی داده های گمشده به طور جداگانه نیست.

  • از نشانگرهای غیر ضروری خودداری کنید برای تمیز نگه داشتن کد GO خود ، حفظ آن آسان است.

با پیروی از این قوانین ساده ، شما می نویسید کد بهتر با سردردهای کمتری!

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

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

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

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