#گولنگ
اگر یک struct گولنگی تعریف کردین که داخلش از mutex استفاده میکنید، حتما باید متدهایی که روی این استراکت تعریف میشن بهصورت پوینتر باشن. اگر این موضوع فراموش بشه، یک نسخه کپی از mutex رو استفاده میکنید و در موقعیتهای همزمانی دچار مشکل میشین.
نمونه کد بد:
نمونه کد خوب:
#tip
#golang
اگر یک struct گولنگی تعریف کردین که داخلش از mutex استفاده میکنید، حتما باید متدهایی که روی این استراکت تعریف میشن بهصورت پوینتر باشن. اگر این موضوع فراموش بشه، یک نسخه کپی از mutex رو استفاده میکنید و در موقعیتهای همزمانی دچار مشکل میشین.
نمونه کد بد:
type User struct {
sync.Mutex
data map[string]string
}
func NewUser() User {
return User{
data: make(map[string]string),
}
}
func (m User) Get(k string) string {
m.Lock()
defer m.Unlock()
return m.data[k]
}
نمونه کد خوب:
type User struct {
mu sync.Mutex
data map[string]string
}
func NewUser() *User {
return &User{
data: make(map[string]string),
}
}
func (m *User) Get(k string) string {
m.mu.Lock()
defer m.mu.Unlock()
return m.data[k]
}
#tip
#golang
👍2🔥1
#گولنگ
معمولا گولنگ دولوپرها تفاوت و کاربرد اسلایسهای empty و nil رو باهم اشتباه میگیرن.
به کد زیر دقت کنید:
کافیه برای اسلایسهای بالا کد زیر رو اجرا کنید تا تفاوت nil و empty بودن رو متوجه بشین:
نتیجه میشه:
خب هرچهار مورد بهعنوان empty در نظر گرفته میشن یعنی اگر len اونارو بگیرین برابر با صفر میشه اما فقط دو مورد اول nil هستن.
دقت کنید:
۱) اسلایسهای nil در واقع empty هم هستن
۲) اسلایسهای nil در حافظه allocation ایجاد نمیکنن
۳) برای هردو نوع اسلایسهای nil و empty میتونیم از تابع append استفاده کنیم
خب پس کاربرد اسلایس nil چیه؟
فرض کنید تابعی دارین که داره یک یا چند اسلایس برمیگردونه، خب دیگه با گولنگ نیازی نیست که مثل زبانهای دیگه یک مقدار allocate شده برگردونید و با برگردوندن nil یا یک اسلایس nil حافظه کمتری مصرف میشه.
#golang
#tip
معمولا گولنگ دولوپرها تفاوت و کاربرد اسلایسهای empty و nil رو باهم اشتباه میگیرن.
به کد زیر دقت کنید:
// #1
var s []string
// #2
s = []string(nil)
// #3
s = []string{}
// #4
s = make([]string, 0)
کافیه برای اسلایسهای بالا کد زیر رو اجرا کنید تا تفاوت nil و empty بودن رو متوجه بشین:
// In Golang "\t" means tab character "\n" means new line
fmt.Printf("IsEmpty=%v \t IsNil=%v \n", len(s) == 0, s == nil)
نتیجه میشه:
#1
IsEmpty=true IsNil=true
#2
IsEmpty=true IsNil=true
#3
IsEmpty=true IsNil=false
#4
IsEmpty=true IsNil=false
خب هرچهار مورد بهعنوان empty در نظر گرفته میشن یعنی اگر len اونارو بگیرین برابر با صفر میشه اما فقط دو مورد اول nil هستن.
دقت کنید:
۱) اسلایسهای nil در واقع empty هم هستن
۲) اسلایسهای nil در حافظه allocation ایجاد نمیکنن
۳) برای هردو نوع اسلایسهای nil و empty میتونیم از تابع append استفاده کنیم
خب پس کاربرد اسلایس nil چیه؟
فرض کنید تابعی دارین که داره یک یا چند اسلایس برمیگردونه، خب دیگه با گولنگ نیازی نیست که مثل زبانهای دیگه یک مقدار allocate شده برگردونید و با برگردوندن nil یا یک اسلایس nil حافظه کمتری مصرف میشه.
func scores() []int {
s, err := apiCall();
if err != nil {
return nil
}
return s
}
#golang
#tip
👏2
#گولنگ
وقتی گوروتینها (goroutine) رو استفاده میکنین باید همیشه مطمئن بشین که پروسه مورد نظرتون چه زمانی به پایان میرسه و در نتیجه اصطلاحا گوروتین خارج میشه.
گوروتینها در گولنگ توسط grabage collector پاکسازی نمیشن و با وجود سبک بودنشون هنوز هم میتونن باعث ایجاد مموری لیک (memory leak) در برنامهتون بشن یا برای همیشه در پسزمینه در حال اجرا باقی بمونن!
این رفتار در گولنگ اشتباه نیست و به برنامهنویس اجازه میده پروسسهای طولانی مدت رو به راحتی در حال اجرا نگهداره، مثلا ایجاد یک وبسرویس که خیلی راحت روی یک گوروتین بلاک شده توسط یک چنل در وضعیت اجرا باقی میمونه اما در بقیه موارد باید حواستون باشه که با نوشتن کد مناسب چرخه عمر گوروتینها رو به درستی کنترل کنید.
ابزارهای زیادی برای مشخص گوروتینهای لیکی وجود دارد. این مقاله در شرکت اوبر (Uber) دید جالبی در این زمینه داره و خوندنش خالی از لطف نیست.
#golang
#tip
وقتی گوروتینها (goroutine) رو استفاده میکنین باید همیشه مطمئن بشین که پروسه مورد نظرتون چه زمانی به پایان میرسه و در نتیجه اصطلاحا گوروتین خارج میشه.
گوروتینها در گولنگ توسط grabage collector پاکسازی نمیشن و با وجود سبک بودنشون هنوز هم میتونن باعث ایجاد مموری لیک (memory leak) در برنامهتون بشن یا برای همیشه در پسزمینه در حال اجرا باقی بمونن!
این رفتار در گولنگ اشتباه نیست و به برنامهنویس اجازه میده پروسسهای طولانی مدت رو به راحتی در حال اجرا نگهداره، مثلا ایجاد یک وبسرویس که خیلی راحت روی یک گوروتین بلاک شده توسط یک چنل در وضعیت اجرا باقی میمونه اما در بقیه موارد باید حواستون باشه که با نوشتن کد مناسب چرخه عمر گوروتینها رو به درستی کنترل کنید.
ابزارهای زیادی برای مشخص گوروتینهای لیکی وجود دارد. این مقاله در شرکت اوبر (Uber) دید جالبی در این زمینه داره و خوندنش خالی از لطف نیست.
#golang
#tip
👍2
#گولنگ
یکی از توصیههای کاربردی و مهم در تابع main برنامههای گولنگی اینه که بهتره نهایتا یکبار از log.Fatal یا os.Exit استفاده کنیم.
یعنی اگر ما در تابع main بخشهای کلیدی و وابستگیهای برنامه مثل دیتابیس و... رو آماده و برای چک کردن هر بخش بارها از log.Fatal استفاده کنیم، بهطور فزاینده و غیرضروری تابع main رو طولانی کردیم و حتی گاها رفتار عجیبی از یک قسمت سر میزنه که مورد انتظار ما نیست.
کد معمولی:
کد بهتر:
#golang
#tip
یکی از توصیههای کاربردی و مهم در تابع main برنامههای گولنگی اینه که بهتره نهایتا یکبار از log.Fatal یا os.Exit استفاده کنیم.
یعنی اگر ما در تابع main بخشهای کلیدی و وابستگیهای برنامه مثل دیتابیس و... رو آماده و برای چک کردن هر بخش بارها از log.Fatal استفاده کنیم، بهطور فزاینده و غیرضروری تابع main رو طولانی کردیم و حتی گاها رفتار عجیبی از یک قسمت سر میزنه که مورد انتظار ما نیست.
کد معمولی:
package main
func main() {
args := os.Args[1:]
if len(args) != 1 {
log.Fatal("file is missing")
}
name := args[0]
f, err := os.Open(name)
if err != nil {
log.Fatal(err)
}
defer f.Close()
// If we call log.Fatal after this line,
// f.Close will not be called.
b, err := io.ReadAll(f)
if err != nil {
log.Fatal(err)
}
db, err := db.New()
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Again, if we call log.Fatal after
// this line, db.Close will not be called.
// ...
}
کد بهتر:
package main
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
args := os.Args[1:]
if len(args) != 1 {
return errors.New("file is missing")
}
name := args[0]
f, err := os.Open(name)
if err != nil {
return err
}
defer f.Close()
b, err := io.ReadAll(f)
if err != nil {
return err
}
db, err := db.New()
if err != nil {
return err
}
defer db.close()
// ...
}
#golang
#tip
👍1
نمونه کد اجرای یک کانکشن SSE در گولنگ:
#tip
#golang
import (
"fmt"
"net/http"
"time"
)
func sseHandler(w http.ResponseWriter, r *http.Request) {
// set SSE http headers
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
// create a channel for client disconnection
clientIsGone := r.Context().Done()
rc := http.NewResponseController(w)
t := time.NewTicker(time.Second)
defer t.Stop()
for {
select {
case <-clientIsGone:
fmt.Println("client disconnected")
return
case <-t.C:
// send event to the client
_, err := fmt.Fprintf(w, "data: the time is %s\n\n", time.Now().Format(time.UnixDate))
if err != nil {
return
}
err = rc.Flush()
if err != nil {
return
}
}
}
}
#tip
#golang
#golang
#tip
مشکل کد زیر کجاست؟
خب این برنامه در ظاهر مشکلی نداره، یک اسلایس تعریف و در خط بعدی ایندکس صفرم دارای مقدار شده، اما نکته مهم اینجاست برای متغیر names یک اسلایس با ظرفیت (capacity) 10، اما طول (length) حقیقی صفر ایجاد شده و هنگامی که در خط بعدی تصمیم به مقداردهی یکی از ایندکسهای اسلایس میکنیم برنامه با خطای رانتایم مواجه میشه و نتیجه چنین کدی مساوی با خطای زیر است:
اگر میخواهید به اسلایسی که طول آن صفر است مقداری را اضافه کنید باید با استفاده از تابع ()append به شکل زیر این کار را انجام دهید.
اما اگر نیاز داریم حتما مقادیر در ایندکسهای مشخص در این اسلایس قرار بگیرند باید تعریف متغیر names را به روش درست زیر انجام دهیم:
در این نوع تعریف علاوهبر تعیین ظرفیت، طول حقیقی اسلایس نیز معین میشه تا از خطای رانتایم جلوگیری شود.
دقت کنید تعریف اسلایس با کلمه کلیدی var و تکرار روند بالا بازهم برنامه را با خطای index out of range روبرو خواهد کرد.
#tip
#golang
#tip
مشکل کد زیر کجاست؟
func main() {
names := make([]string, 0, 10)
names[0] = "reza"
fmt.Println(names)
}
خب این برنامه در ظاهر مشکلی نداره، یک اسلایس تعریف و در خط بعدی ایندکس صفرم دارای مقدار شده، اما نکته مهم اینجاست برای متغیر names یک اسلایس با ظرفیت (capacity) 10، اما طول (length) حقیقی صفر ایجاد شده و هنگامی که در خط بعدی تصمیم به مقداردهی یکی از ایندکسهای اسلایس میکنیم برنامه با خطای رانتایم مواجه میشه و نتیجه چنین کدی مساوی با خطای زیر است:
panic: runtime error: index out of range [0] with length 0
اگر میخواهید به اسلایسی که طول آن صفر است مقداری را اضافه کنید باید با استفاده از تابع ()append به شکل زیر این کار را انجام دهید.
names = append(names, "reza")
اما اگر نیاز داریم حتما مقادیر در ایندکسهای مشخص در این اسلایس قرار بگیرند باید تعریف متغیر names را به روش درست زیر انجام دهیم:
names := make([]string, 10)
در این نوع تعریف علاوهبر تعیین ظرفیت، طول حقیقی اسلایس نیز معین میشه تا از خطای رانتایم جلوگیری شود.
دقت کنید تعریف اسلایس با کلمه کلیدی var و تکرار روند بالا بازهم برنامه را با خطای index out of range روبرو خواهد کرد.
var ages []int
ages[1] = 29 // this line will fail with runtime error: index out of range [1] with length 0
#tip
#golang
⚡1🔥1😱1
گولنگ ۱.۲۴ در ماه فوریه ۲۰۲۵ ارائه میشه و بالاخره توسعههندگان تصمیم گرفتن تگ omitzero رو برای پکیج encoding/json فعال کنن و از این به بعد با نوشتن این تگ علاوه بر مقادیر پیشفرض، استراکچرهای خالی هم حذف میشن!
در ورژنهای فعلی گولنگ تگ omitempty رو داشتیم اما تنها فیلدهای با مقادیر پیش فرض رو حذف میکرد.
یه نگاه به نمونه کد زیر بندازین تا بیشتر موضوع روشن بشه:
تگ omitempty استراکچر درونی Posts رو حذف نمیکنه و فقط فیلدهای Name و Tags رو به شرطی حذف میکنه که مقدار پیشفرض گولنگی خودشون رو داشته باشن.
برای اینکه این مقادیر رو حذف کنید باید اینترفیس marshaler رو خودتون برای استراکت پیادهسازی کنید اما با ورژن ۱.۲۴ با تگ omitzero استراکتهای خالی به شکل خودکار حذف میشن.
لینک ریلیز ۱.۲۴ گولنگ برای جزییات بیشتر:
https://tip.golang.org/doc/go1.24
#tip
#golang
در ورژنهای فعلی گولنگ تگ omitempty رو داشتیم اما تنها فیلدهای با مقادیر پیش فرض رو حذف میکرد.
یه نگاه به نمونه کد زیر بندازین تا بیشتر موضوع روشن بشه:
type Blog struct {
Name string `json:"omitempty"`
Tags []string `json:"omitempty"`
Posts Posts `json:"omitempty"`
}
تگ omitempty استراکچر درونی Posts رو حذف نمیکنه و فقط فیلدهای Name و Tags رو به شرطی حذف میکنه که مقدار پیشفرض گولنگی خودشون رو داشته باشن.
برای اینکه این مقادیر رو حذف کنید باید اینترفیس marshaler رو خودتون برای استراکت پیادهسازی کنید اما با ورژن ۱.۲۴ با تگ omitzero استراکتهای خالی به شکل خودکار حذف میشن.
type Blog struct {
Name string `json:"omitzero"`
Tags []string `json:"omitzero"`
Posts Posts `json:"omitzero"`
}
لینک ریلیز ۱.۲۴ گولنگ برای جزییات بیشتر:
https://tip.golang.org/doc/go1.24
#tip
#golang
👏5
اگر در اپلیکیشنی که دارید زیاد از time.Time استفاده میکنید میتونید با استفاده از ایجاد یک تایپ دلخواه و استفاده int64 میزان مصرف مموری رو تا حد قابل قبولی کاهش بدید و پرفورمنس رو بهتر کنید. به مثال زیر دقت کنید:
#tip
#golang
type Timestamp int64
func (t Timestamp) Time() time.Time {
return time.Unix(int64(t), 0)
}
#tip
#golang
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
پکیج go-tmpl بهتون این امکان رو میده خیلی ساده کدهای گولنگ رو با HTML ترکیب کنید. هرچند که خود استانداد لایبرری گولنگ از این موضوع پشتیبانی میکنه اما خب این پکیج امکانات جالبی داره که در ویدیو بالا میتونید ببینید.
https://github.com/a-h/templ
#golang
#packge
https://github.com/a-h/templ
#golang
#packge
👍6
تمام تغییرات زبان گولنگ در نسخه 1.24 رو در لینک زیر مشاهده و اجرا کنید!
لینک زیر یک محیط تعاملی برای درک بهتر قابلیتهای Golang در ورژن 1.24 است.
https://antonz.org/go-1-24/
#golang
#tip
لینک زیر یک محیط تعاملی برای درک بهتر قابلیتهای Golang در ورژن 1.24 است.
https://antonz.org/go-1-24/
#golang
#tip
antonz.org
Go 1.24 interactive tour
Weak pointers, faster maps, directory-scoped access, and more.
👏2⚡1
نوشتن middleware برای اجرا مجموعهای پروسهها قبل از رسیدن درخواست به هندلر برای gRPC سرور کار دشواری نیست.
اما خب اگر تمایل دارین پکیجی استفاده کنین که خودش خودکار لاگ بزنه و ردیابی رو با استانداردهای Otel در اختیارتون قرار بده و مواردی
مثل:
Auth,
Metrics (Prometheus),
Logging,
Selector,
Validator,
Ratelimit
و غیره رو خیلی راحتتر داشته باشین، یه نگاهی به پکیج زیر بندازین.
نمونه کد:
https://github.com/grpc-ecosystem/go-grpc-middleware
#package
#golang
اما خب اگر تمایل دارین پکیجی استفاده کنین که خودش خودکار لاگ بزنه و ردیابی رو با استانداردهای Otel در اختیارتون قرار بده و مواردی
مثل:
Auth,
Metrics (Prometheus),
Logging,
Selector,
Validator,
Ratelimit
و غیره رو خیلی راحتتر داشته باشین، یه نگاهی به پکیج زیر بندازین.
نمونه کد:
grpcSrv := grpc.NewServer(
grpc.StatsHandler(otelgrpc.NewServerHandler()),
grpc.ChainUnaryInterceptor(
srvMetrics.UnaryServerInterceptor(grpcprom.WithExemplarFromContext(exemplarFromContext)),
logging.UnaryServerInterceptor(interceptorLogger(rpcLogger), logging.WithFieldsFromContext(logTraceID)),
selector.UnaryServerInterceptor(auth.UnaryServerInterceptor(authFn), selector.MatchFunc(allButHealthZ)),
recovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpcPanicRecoveryHandler)),
),
)
https://github.com/grpc-ecosystem/go-grpc-middleware
#package
#golang
👍3🙏1
اگر دوستدارین best practiceها و نکات ریزی که حین استفاده از defer در گولنگ بهش برخورد میکنید رو بدونید و از اشتباهات رایج جلوگیری کنید، مقاله زیر بهتون کمک میکنه.
https://rezakhademix.medium.com/defer-functions-in-golang-common-mistakes-and-best-practices-96eacdb551f0
#tip
#golang
https://rezakhademix.medium.com/defer-functions-in-golang-common-mistakes-and-best-practices-96eacdb551f0
#tip
#golang
Medium
Defer Functions in Golang: Common Mistakes and Best Practices
This story will focus on defer functions in Golang, providing a comprehensive guide to help us understand them better and…
👍4🙏1
مقاله زیر با زبان خیلی ساده به ما میگه که چطور از اشتباهات پیشپا افتاده جلوگیری کنیم و بتونیم اپلیکیشن گولنگی که داریم به برای تعداد رکوئست بالا آماده کنیم.
https://dev.to/rikenshah/scaling-backend-to-1m-requests-with-just-2gb-ram-4m0c
#tip
#golang
https://dev.to/rikenshah/scaling-backend-to-1m-requests-with-just-2gb-ram-4m0c
#tip
#golang
DEV Community
Avoiding Beginner Mistakes Hampering You to Scale Backend⚡️
This blog covers how I unlocked performance that allowed me to scale my backend from 50K requests →...
👍4🔥1
سوال #استخدامی:
اگر فانکشن modify رو به شکل زیر تعریف و سپس تابع main رو با بدنه نوشته اجرا کنیم، در نتیجه کدام یک از گزینهها چاپ خواهد شد؟
1. Compilation Error
2. [100, 200, 300, 4]
3. [1, 2, 3, 4]
4. [100, 200, 300, 0]
در زبان Go، تابع copy(dest, src) عناصر src را در dest کپی میکند، اما اندازه dest را تغییر نمیدهد.
در اینجا، دستور
سه عنصر اول آرایه nums را جایگزین میکند، اما طول اصلی آن را تغییر نمیدهد.
بنابراین، وقتی fmt.Println(nums) را اجرا کنیم، خروجی
خواهد بود. (گزینه دو)
#golang
#qa
اگر فانکشن modify رو به شکل زیر تعریف و سپس تابع main رو با بدنه نوشته اجرا کنیم، در نتیجه کدام یک از گزینهها چاپ خواهد شد؟
1. Compilation Error
2. [100, 200, 300, 4]
3. [1, 2, 3, 4]
4. [100, 200, 300, 0]
func modify(s []int){
copy(s, []int{100, 200, 300})
}
func main(){
nums := []int{1, 2, 3, 4}
modify(nums)
fmt.Println(nums)
}
در زبان Go، تابع copy(dest, src) عناصر src را در dest کپی میکند، اما اندازه dest را تغییر نمیدهد.
در اینجا، دستور
copy(nums, []int{100, 200, 300})
سه عنصر اول آرایه nums را جایگزین میکند، اما طول اصلی آن را تغییر نمیدهد.
بنابراین، وقتی fmt.Println(nums) را اجرا کنیم، خروجی
[100, 200, 300, 4]
خواهد بود. (گزینه دو)
#golang
#qa
👍7👏2
اگر دوستدارین best practiceها و نکات ریزی که حین استفاده از sliceها در گولنگ بهش برخورد میکنید رو بدونید و از اشتباهات رایج جلوگیری کنید، مقاله زیر بهتون کمک میکنه.
https://rezakhademix.medium.com/slices-in-golang-common-mistakes-and-best-practices-76c30857d4e4
#tip
#golang
https://rezakhademix.medium.com/slices-in-golang-common-mistakes-and-best-practices-76c30857d4e4
#tip
#golang
Medium
Slices in Golang: Common Mistakes and Best Practices
In this story we want to discuss about slices in Golang and see some different scenarios to avoid common mistakes like:…
👍4👨💻1
اگر دوستدارین best practiceها و نکات ریزی که حین استفاده از stringها در گولنگ بهش برخورد میکنید رو بدونید و از اشتباهات رایج جلوگیری کنید، مقاله زیر بهتون کمک میکنه.
https://rezakhademix.medium.com/strings-in-golang-common-mistakes-and-best-practices-1250045051f8
#tip
#golang
https://rezakhademix.medium.com/strings-in-golang-common-mistakes-and-best-practices-1250045051f8
#tip
#golang
Medium
Strings in Golang: Common Mistakes and Best Practices
In this story we want to discuss about strings in Golang and see some different scenarios to avoid common mistakes like:…
❤2👍2
زمانی که با گولنگ توسعه میدیم باید دقت خوبی در استفاده از گوروتینها، کنترل پوینترها و موضوعات دیگر با هدف جلوگیری از مموریلیک داشته باشیم.
ابزارهای مانیتورینگ و پروفایل کردن برنامه گولنگی مثل: pprof و Prometheus و... هم کمک خوبی برای تشخیص بهتر اشتباهات توسعه و مموریلیک هستند.
اما سورپرایز ویژه اضافه شدن دستور
هستش که قرار هست به گولنگ ۱.۲۵ اضافه شود و با دقت خوبی، مموریلیکهای برنامه رو در هنگام خروج مشخص نماید.
#golang
ابزارهای مانیتورینگ و پروفایل کردن برنامه گولنگی مثل: pprof و Prometheus و... هم کمک خوبی برای تشخیص بهتر اشتباهات توسعه و مموریلیک هستند.
اما سورپرایز ویژه اضافه شدن دستور
go build -asan
هستش که قرار هست به گولنگ ۱.۲۵ اضافه شود و با دقت خوبی، مموریلیکهای برنامه رو در هنگام خروج مشخص نماید.
#golang
👍9🔥3❤1
بعد از مدتها بالاخره Gorm آپدیتی که اکثر برنامهنویسان گولنگ منتظرش بودند رو در نسخه جدید منتشر کرد.
در کامیونیتی گولنگ Gorm بخاطر عدم Type Safty و پیچیدگیهای مختلف آنچنان محبوب نیست. مدتها بود که Generic ها به زبان گولنگ اضافه شدن اما با وجود درخواستهای زیاد، همچنان در Gorm مورد استفاده قرار نگرفته بودند تا اینکه در ورژن جدید Gorm یعنی V1.30.0 بالاخره این قابلیت به Gorm اضافه شده و میتونه برگ برندهای برای این ORM باشه.
شخصا از Gorm بخاطر عدم بهینه بودن، رفتار عجیب و… استفاده نمیکردم اما این آپدیت آنقدر جدی هست که در صفحه اول داکیومنت Gorm خیلی شفاف به این قابلیت پرداخته و تاکید کرده فقط در ورژنهای V1.30 به بالا قابل استفاده است. شخصا مایلم یک بار دیگه تستش کنم و ببینم تونسته مشکلات متعددی که داشت رو رفع کنه یا خیر!
به نظرم بهزودی این سینتکس جدید، به روش پیشفرض کوئری نوشتن در Gorm تبدیل میشه!
#gorm
#golang
@cloudygo
در کامیونیتی گولنگ Gorm بخاطر عدم Type Safty و پیچیدگیهای مختلف آنچنان محبوب نیست. مدتها بود که Generic ها به زبان گولنگ اضافه شدن اما با وجود درخواستهای زیاد، همچنان در Gorm مورد استفاده قرار نگرفته بودند تا اینکه در ورژن جدید Gorm یعنی V1.30.0 بالاخره این قابلیت به Gorm اضافه شده و میتونه برگ برندهای برای این ORM باشه.
شخصا از Gorm بخاطر عدم بهینه بودن، رفتار عجیب و… استفاده نمیکردم اما این آپدیت آنقدر جدی هست که در صفحه اول داکیومنت Gorm خیلی شفاف به این قابلیت پرداخته و تاکید کرده فقط در ورژنهای V1.30 به بالا قابل استفاده است. شخصا مایلم یک بار دیگه تستش کنم و ببینم تونسته مشکلات متعددی که داشت رو رفع کنه یا خیر!
به نظرم بهزودی این سینتکس جدید، به روش پیشفرض کوئری نوشتن در Gorm تبدیل میشه!
#gorm
#golang
@cloudygo
❤2👍2👏2