ผู้รับและอินเตอร์เฟซ

วิธีที่มีผู้รับค่าสามารถเรียกใช้ได้โดยใช้อีกทั้งค่าและพอยน์เตอร์

วิธีที่มีผู้รับพอยน์เตอร์สามารถถูกเรียกใช้ได้เฉพาะโดยใช้พอยน์เตอร์หรือ ค่าที่สามารถทำให้เข้าถึงได้

ตัวอย่างเช่น

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()

// ส่วนนี้จะไม่สามารถคอมไพล์ได้:
// 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

// โค้ดด้านล่างนี้จะไม่คอมไพล์เนื่องจาก s2Val เป็นค่า และวิธี f ของ S2 ไม่มีผู้รับค่า
// i = s2Val

Effective Go มีคำอธิบายเยี่ยมเกี่ยวกับ pointers vs. values.

หมายเหตุเพิ่มเติม:

  • ชนิดหนึ่งสามารถมีชุดวิธีที่มีผู้รับค่า และชุดวิธีที่มีผู้รับพอยน์เตอร์
    • ชุดวิธีที่มีผู้รับค่าเป็นซับเซ็ตของชุดวิธีที่มีผู้รับพอยน์เตอร์ แต่ไม่ใช่ทางกลับ
  • กฎ
    • วัตถุค่าสามารถใช้ชุดวิธีที่มีผู้รับค่าเท่านั้น
    • วัตถุพอยน์สามารถใช้ชุดวิธีที่มีผู้รับค่า + ชุดวิธีที่มีผู้รับพอยน์เตอร์

การตรงตอกันอินเตอร์เฟซ (หรือการนำมาใช้) - ชนิดตรงตอกันกับอินเตอร์เฟซ หากมันทำการนำมาใช้วิธีทั้งหมดของอินเตอร์เฟซ - โดยเฉพาะ, มันเป็นการนำมาใช้ชุดวิธีของค่าของชนิดตรงตอกันกับอินเตอร์เฟซหรือชุดวิธีของพอยน์ที่ตรงตอกันกับอินเตอร์เฟซ

มีการตรงตอกันสองประเภท:

  • ชุดวิธีของค่าที่ตรงตอกันกับอินเตอร์เฟซ
    • สามารถนำเข้าสู่ตัวแปรอินเตอร์เฟซได้ เนื่องจากรวมทั้งสอดคล้องกับชุดวิธีของค่าและพอยน์ทั้งสองมีชุดวิธีของค่า
  • ชุดวิธีของพอยน์ที่ตรงตอกันกับอินเตอร์เฟซ
    • เฉพาะวัตถุพอยน์เท่านั้นที่สามารถนำเข้าสู่ตัวแปรอินเตอร์เฟซได้เพราะประเภทของพอยน์สอดคล้องกับอินเตอร์เฟซ
    • หากนำวัตถุค่าเข้าสู่ตัวแปรอินเตอร์เฟซ จะทำให้เกิดการทดสอบความมีชีวิตของอินเตอร์เฟซขณะคอมไพล์

ส่วนที่เกี่ยวกับเหตุผลที่ i = s2Val ทำให้เกิดข้อผิดพลาดนั้นเป็นเพราะชุดวิธีของค่าและอินเตอร์เฟซไม่ตรงกันและเกิดข้อผิดพลาด