گیرنده و رابط
متدهایی که دارای گیرندههای مقدار هستند، میتوانند با استفاده از هر دو مقدار و اشارهگرها فراخوانی شوند.
متدهایی که دارای گیرندههای اشارهگر هستند، تنها میتوانند با استفاده از اشارهگر یا مقادیر قابل آدرسدهی فراخوانی شوند.
به عنوان مثال:
type S struct {
data string
}
func (s S) Read() string {
return s.data
}
func (s *S) Write(str string) {
s.data = str
}
sVals := map[int]S{1: {"A"}}
// تنها میتوانید از یک مقدار برای فراخوانی Read استفاده کنید
sVals[1].Read()
// این قطعاً compile نمیشود:
// sVals[1].Write("test")
sPtrs := map[int]*S{1: {"A"}}
// هر دو متد Read و Write میتوانند با استفاده از یک اشارهگر فراخوانی شوند
sPtrs[1].Read()
sPtrs[1].Write("test")
به همین ترتیب، حتی اگر یک متد دارای گیرنده مقدار باشد، میتواند یک رابط را با استفاده از گیرنده اشارهگر رضایت بخش باشد.
type F interface {
f()
}
type S1 struct{}
func (s S1) f() {}
type S2 struct{}
func (s *S2) f() {}
s1Val := S1{}
s1Ptr := &S1{}
s2Val := S2{}
s2Ptr := &S2{}
var i F
i = s1Val
i = s1Ptr
i = s2Ptr
// کد زیر compile نخواهد شد زیرا s2Val یک مقدار است و متد f از S2 دارای گیرنده مقدار نیست
// i = s2Val
گوگولنگ مفاهیم عالی در مورد اشارهگرها در مقابل مقادیر را در Effective Go شرح داده است.
یادداشتهای اضافی:
- یک نوع میتواند مجموعه متدهای دارای گیرندههای مقدار و مجموعه متدهای دارای گیرندههای اشارهگر را داشته باشد
- مجموعه متدهای دارای گیرندههای مقدار زیرمجموعهای از مجموعه متدهای دارای گیرندههای اشارهگر است، اما برعکس صدق نمیکند
- قوانین
- اشیاء مقدار تنها میتوانند از مجموعه متدهای دارای گیرندههای مقدار استفاده کنند
- اشیاء اشارهگر میتوانند از مجموعه متدهای دارای گیرندههای مقدار + مجموعه متدهای دارای گیرندههای اشارهگر استفاده کنند
- بازتاب رابط (یا پیادهسازی)
- نوع با رابط همخوانی دارد اگر همه متدهای رابط را پیادهسازی کند
- بهطور خاص، یا مجموعه متدهای مقدار نوع با متدهای رابط همخوانی دارد یا مجموعه متدهای اشارهگر با رابط همخوانی دارد
دو نوع خاص از همخوانی وجود دارد:
- همخوانی مجموعه متدهای مقدار با رابط
- مجموعه متدهای مقدار وجود دارد، امکان اختصاص یک اشیاء مقدار یا اشارهگر به یک متغیر رابطی وجود دارد، زیرا هر دو حاوی مجموعه متدهای مقدار هستند
- همخوانی مجموعه متدهای اشارهگر با رابط
- تنها یک اشیاء اشارهگر میتواند به یک متغیر رابطی اختصاص داده شود، زیرا تنها مجموعه متدهای اشارهگر با رابط همخوانی دارد
- اگر یک اشیاء مقدار به یک متغیر رابطی اختصاص داده شود، در طول اجرا، مکانیزم بررسی زنده رابط به وجود خواهد آمد
در مورد اینکه چرا i = s2Val خطایی ایجاد میکند، دلیل آن این است که مجموعه متدهای مقدار و رابط هماهنگی ندارند.