บันทึก Golang #01 Receiver ต่างกับ Function อย่างไร

โปรดจงเรียกข้าว่า method in type

บทความนี้ผมตั้งใจจะบันทึกเรื่องราวชวนน่าค้นหาในภาษา Go เก็บไว้ ซึ่งแต่ละบทความจะไม่เน้น Basic Go มากนัก เพราะ หาอ่านได้หลายที่ โดยเนื้อหาที่ผมเน้น คือ เจาะลึกลงไป เพื่อให้เห็นว่าภาษา Go นั้น แตกต่าง หรือ มีแนวคิดอย่างไร เมื่อเทียบกับ ภาษาอื่นๆ และในวันนี้จะขอเริ่มจากเรื่องราวของ …“Receiver ต่างกับ Function อย่างไร?”…

สิ่งที่เราต้องรู้คือ Go ไม่มี Class

นั่นหมายความว่า เราจะไม่มี method ที่สามารถเข้าถึง element ใน object เราได้

เช่น การเข้าถึง member ใน object ด้วย keyword this ใน JavaScript

const profile = {  firstname: 'foo',  lastname: 'bar',  getFullname: () => `${this.firstname} ${this.lastname}`
};
profile.getFullname(); // "foo bar"

แล้วถ้าหากเราต้องการ concept นี้ ให้ประยุกต์ใช้กับภาษา Go จะทำได้ไหม คำตอบ คือ ได้ครับ เราเรียกวิธีการนั้นว่า “Receiver”

Receiver คืออะไร?

Go does not have classes. However, you can define methods on types.

A method is a function with a special receiver argument.

จากประโยค ข้างบน method != function ลองดูที่นี่ เพื่อเห็นภาพมากขึ้น

Function คือ กลุ่มของ Code มี/ไม่มี parameter และ มี/ไม่มี return value

Method คือ เหมือนกับ function แต่จะเกี่ยวของกับ scope ของ object/class หรือ อยู่ภายใต้ object

Method ใน Go คือ function ที่มี receiver argument

การที่จะให้ Method ผูกติดเฉพาะ member ที่เราระบุนั้น เราจำเป็นต้องสร้างสิ่งที่เรียกว่า Receiver ขึ้นมา โดยจะผูกติดกับ type ที่เรากำหนดขึ้น

วิธีการสร้าง Receiver method

กำหนด type

type Profile struct {  firstname string  lastname  string}

สร้าง Receiver method ที่มี argument type Profile

func (p Profile) getFullname() string {  return p.firstname + " " + p.lastname}

จากโค๊ดข้างบนเราได้สร้าง receiver method ขึ้นมา โดยมี argument p ซึ่งมี type Profile และเมื่อมีการเรียก receiver method คนที่เรียกจะได้คุณสมบัติ getFullname() ติดไปด้วย

Binding receiver method เข้าตัวแปร

func main() {  f := Profile{"Teerapong", "Singthong"}  fmt.Println(f.getFullname())}

ทำการสร้างตัวแปร f ขึ้นมา โดยกำหนดให้มี type Profile และทำการกำหนดค่า ซึ่งจะเห็นได้ว่า ตัวแปร f สามารถใช้ . (dot reference) หา method getFullname() ได้ คล้ายกับภาษาที่รองรับ object

ลองดูอีกตัวอย่าง

https://www.slideshare.net/fmamud/ftd-golang

ถ้าหากมีการ เรียก receiver method ผ่านการกำหนด type reat เช่น

cal := rect{100, 200}// ตัวแปร cal จะมี area() และ perim() ติดมาด้วย

สรุป การใช้ method receiver คือ การให้ golang มีคุณสมบัติคล้ายกับการทำงานแบบ keyword this หรือ เป็นการ binding method เข้า type ที่เรากำหนดนั่นเอง

หรือจะมองว่า method in type ก็คงไม่ผิดนัก

อย่าสับสนระหว่าง method receiver กับ function นะครับ เพราะจริงๆ แล้วคนละวิธีการกันเลย และมีจุดประสงค์ต่างกัน จำไว้เลยว่า method receiver จะมี scope manipulate data ได้กับแค่ type ที่มันทำงานด้วยเท่านั้น

— golf

--

--

Teerapong Singthong 👨🏻‍💻
Teerapong Singthong 👨🏻‍💻

Written by Teerapong Singthong 👨🏻‍💻

Engineering Manager, ex-Solution Engineering Lead at LINE | Tech | Team Building | System Design | Architecture | SWE | Large Scaling System

No responses yet