به زبان ساده، این پروپوزال میخواهد امکان تعریف متدهای جنریک (دارای پارامتر نوع) را برای تایپهای معمولی (Concrete Types) فراهم کند، چیزی که تا الان در Go وجود نداشته است.
۱. مشکل فعلی چیست؟
در حال حاضر در Go، شما میتوانید «توابع جنریک» (Generic Functions) داشته باشید، اما نمیتوانید «متدهای جنریک» داشته باشید.
مثلاً الان این کد مجاز نیست:
// الان خطا میدهد
func (s *Set) Add[T any](val T) { ... }
دلیل تاریخی این محدودیت این بود که تیم Go معتقد بود اگر به متدها اجازه جنریک بودن بدهند، باید این اجازه را به interfaceها هم بدهند. اما پیادهسازی متدهای جنریک در اینترفیسها به دلیل ماهیت داینامیک Go بسیار پیچیده و پرهزینه است.
۲. تغییر دیدگاه (راه حل پیشنهادی)
این پروپوزال میگوید بیایید نگاهمان را عوض کنیم:
* متدهای روی تایپهای معمولی (مثل structها) صرفاً برای پیادهسازی اینترفیسها نیستند. آنها برای سازماندهی کد و خوانایی هم مفیدند.
* بنابراین، بیایید اجازه دهیم متدهای معمولی (Concrete Methods) جنریک باشند، اما متدهای اینترفیس همچنان ساده باقی بمانند.
۳. نحوه کارکرد (سینتکس جدید)
پیشنهاد این است که تعریف متدها دقیقاً شبیه توابع جنریک شود. یعنی بتوانید بعد از نام متد، پارامتر نوع (Type Parameter) بگذارید.
مثال پیشنهادی:
type S struct {}
// متد m یک متد جنریک است که پارامتر P را میگیرد
func (r *S) m[P any](x P) {
// ...
}
func main() {
var s S
// فراخوانی با آرگومان صریح
s.m[int](42)
// فراخوانی با استنتاج نوع (Type Inference)
s.m("hello")
}۴. محدودیت مهم (نکته کلیدی)
این مهمترین بخش پروپوزال است که باید درک شود: متدهای جنریک نمیتوانند اینترفیسهای موجود را Implement کنند.
چون اینترفیسها در Go نمیتوانند متد جنریک داشته باشند، پس یک متد جنریک روی یک استراکت، هیچوقت با یک متد ساده در اینترفیس تطابق (Match) نخواهد داشت.
مثال:
اگر شما یک متد
Read[E any](b []E) داشته باشید، این متد اینترفیس io.Reader را پیادهسازی نمیکند، چون io.Reader انتظار متد Read([]byte) را دارد، نه یک متد جنریک.۵. چرا این قابلیت مفید است؟
* سازماندهی کد: به جای نوشتن توابع جنریک جداگانه (مثل slices.Map(s, fn)), میتوانید آنها را به صورت متد بنویسید (مثل s.Map(fn)).
* زنجیرهسازی (Chaining): باعث میشود کد خواناتر شود. مثلاً x.Filter(...).Map(...) به جای Map(Filter(x, ...), ...).
https://github.com/golang/go/issues/77273
➖➖➖➖➖➖➖➖
⚡️@GoInsights | @GolangEngineers


