<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Perajit</title>
    <description>The latest articles on DEV Community by Perajit (@perajit).</description>
    <link>https://dev.to/perajit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3889814%2F9fd0b414-7ecd-47a0-9a41-67960fda3f4d.png</url>
      <title>DEV Community: Perajit</title>
      <link>https://dev.to/perajit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/perajit"/>
    <language>en</language>
    <item>
      <title>Interface in Go ฉบับรวบยอด</title>
      <dc:creator>Perajit</dc:creator>
      <pubDate>Tue, 21 Apr 2026 01:27:11 +0000</pubDate>
      <link>https://dev.to/perajit/interface-in-go-chbabrwbyd-1c3e</link>
      <guid>https://dev.to/perajit/interface-in-go-chbabrwbyd-1c3e</guid>
      <description>&lt;h1&gt;
  
  
  Interface กับ OOP
&lt;/h1&gt;

&lt;p&gt;จากบทความที่แล้ว เราทำ OOP ด้วยการผูก method ให้ struct ผ่าน receiver ทีนี้ถ้าเราอยากจัดการกับ struct หลายประเภทที่มีพฤติกรรมเหมือนกันในที่เดียวจะทำยังไง?&lt;/p&gt;

&lt;p&gt;ปกติในภาษาอื่นเราก็จะสร้าง interface ขึ้นมา แล้วให้แต่ละ class implement interface นั้นใช่มั้ย? ใน Go ก็มี interface เหมือนกัน แต่สิ่งที่ต่างคือ ใน Go เป็น implicit interface ไม่ต้องมีการเขียนคีย์เวิร์ด implement เลย&lt;/p&gt;

&lt;p&gt;เช่น เรามี &lt;code&gt;Cat&lt;/code&gt; และ &lt;code&gt;Dog&lt;/code&gt; ซึ่งทั้งคู่มี method ที่มี method signature เหมือนกันคือ &lt;code&gt;Speaker()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Meow!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Woof!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราสามารถสร้าง interface ได้แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Speaker&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;โดย &lt;code&gt;Cat&lt;/code&gt; และ &lt;code&gt;Dog&lt;/code&gt; ของเราจะยังเหมือนเดิม ไม่มีแก้โค้ดใดๆ แต่ Go จะรู้เองว่ามันคือ &lt;code&gt;Speaker&lt;/code&gt; เพราะว่า "satisfy interface"&lt;/p&gt;

&lt;p&gt;และเราก็สามารถประกาศ slice ของ &lt;code&gt;Speaker&lt;/code&gt; แล้วเก็บค่า &lt;code&gt;Cat&lt;/code&gt; กับ &lt;code&gt;Dog&lt;/code&gt; ไว้ด้วยกัน รวมถึงสามารถเรียก method ของ &lt;code&gt;Speaker&lt;/code&gt; จาก slice ได้เลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Kitty"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Bo"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// slice ของ Speaker เก็บได้ทั้ง cat และ dog ทันที&lt;/span&gt;
&lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Speaker&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;// เรียก Speak() ของ Speaker ได้เลย&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;การที่ทำ interface ในรูปแบบนี้เพราะ Go เชื่อในความอิสระ โดยใช้แนวคิด Duck Typing (ถ้ามันเดินเหมือนเป็ด ร้องเหมือนเป็ด มันก็ย่อมเป็นเป็ด)&lt;/p&gt;

&lt;p&gt;เทียบกับใน classic OOP ซึ่งเวลาจะใช้ interface ต้องมีการผูกกันตั้งแต่ต้น การประกาศ interface จากฝั่ง consumer ใน Go ข้อดีหลายอย่าง&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ทำให้เราโฟกัสที่ behavior มากกว่า type&lt;/li&gt;
&lt;li&gt;ยืดหยุ่น สามารถเอา library สองตัวจากคนละที่มาทำงานร่วมกันได้ทันทีถ้า method signature ตรงกัน&lt;/li&gt;
&lt;li&gt;ไม่ผูกติดกับโค้ดต้นทาง ถ้าสนใจ method ไหนก็ประกาศ interface แค่นั้นพอ ซึ่งข้อนี้ทำให้การ mock (เช่นสำหรับ unit test) ง่ายขึ้นมาก&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  โครงสร้าง Interface
&lt;/h1&gt;

&lt;p&gt;ภายใต้ตัวแปร interface จะเก็บค่า 2 อย่างเสมอ คือ type (ชนิดของข้อมูล) และ value (ค่าของข้อมูล) เพราะฉะนั้น interface จะเป็น &lt;code&gt;nil&lt;/code&gt; ก็ต่อเมื่อทั้ง type และ value เป็น &lt;code&gt;nil&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;เช่นจากตัวอย่างเดิม เรามี struct &lt;code&gt;Cat&lt;/code&gt; และ interface &lt;code&gt;Speaker&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;Speaker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;

&lt;span class="c"&gt;// ตรวจสอบว่า i เป็น nil รึเปล่า&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จะได้ผลลัพธ์เป็น &lt;code&gt;false&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Empty Interface
&lt;/h1&gt;

&lt;p&gt;interface ว่าง &lt;code&gt;interface{}&lt;/code&gt; คือ interface ที่ไม่มีการกำหนด method อะไรไว้ ซึ่งหมายความว่าสามารถเป็น type อะไรก็ได้ (หรือก็คือ &lt;code&gt;any&lt;/code&gt; ในเวอร์ชั่นใหม่ๆ ของ Go)&lt;/p&gt;

&lt;p&gt;เรามักจะใช้ในกรณีที่ต้องการ Dynamic Type เช่น ใช้กับฟังก์ชั่นที่รับพารามิเตอร์อะไรก็ได้ หรือใช้กับโครงสร้างข้อมูลที่ dynamic เช่น &lt;code&gt;map[string]interface{}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;แต่ข้อควรระวังคือ เราจะไม่สามารถใช้ความสามารถของ type เดิมได้ ต้องแปลงค่ากลับมาก่อน เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราไม่สามารถสั่งแบบนี้ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="c"&gt;// จะ error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เนื่องจากตอนนี้ x เป็น interface{} ไม่ใช่ int ต้องแปลงกลับเป็น int ก่อนถึงจะทำ operation ของ int ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;ปัจจุบัน Go มี Generics ให้ใช้แล้ว แนะนำให้ใช้ Generics แทน interface{}&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>OOP ใน Go ฉบับเข้าใจง่าย (มั้ง)</title>
      <dc:creator>Perajit</dc:creator>
      <pubDate>Tue, 21 Apr 2026 00:17:37 +0000</pubDate>
      <link>https://dev.to/perajit/oop-ain-go-chbabekhaaaicchngaay-mang-3j2l</link>
      <guid>https://dev.to/perajit/oop-ain-go-chbabekhaaaicchngaay-mang-3j2l</guid>
      <description>&lt;p&gt;ออกตัวก่อนว่าไม่ได้เชี่ยวชาญ Go อะไรมากมาย แค่นึกไม่ออกว่าเขียนเรื่องอะไรดี แล้วเรื่องนี้ก็ผุดขึ้นมา&lt;/p&gt;

&lt;p&gt;ใน Go สามารถทำ OOP ได้ แต่จะค่อนข้างต่างจากภาษาอื่นที่เคยเจอมา คือไม่มีสิ่งที่เรียกว่า class แต่จะใช้ struct ซึ่งเป็นการ define โครงสร้างข้อมูล เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
  &lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เป็นการประกาศโครงสร้างของข้อมูลที่ประกอบด้วยฟิลด์ชื่อ &lt;code&gt;Name&lt;/code&gt; และ &lt;code&gt;Weight&lt;/code&gt; และเนื่องจากใน Go จะใส่ zero value ให้ค่าต่างๆ เสมอ ดังนั้นถ้าประกาศตัวแปรด้วย type ของ struct แต่ละ field ก็จะมีค่าเริ่มต้นเป็น zero value ของแต่ละชนิดข้อมูลโดยอัตโนมัติ ซึ่งก็คือทำหน้าที่เก็บข้อมูลได้เหมือน data class ในภาษาอื่นนั่นเอง&lt;/p&gt;

&lt;p&gt;จากตัวอย่าง &lt;code&gt;Cat&lt;/code&gt; ถ้าประกาศตัวแปรแบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราก็จะได้สิ่งที่เหมือนกับ instance ของ data class ที่มีค่า &lt;code&gt;cat.Name = ""&lt;/code&gt; และ &lt;code&gt;cat.Weight = 0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;หรือจะกำหนดค่าเริ่มต้นลงไปตั้งแต่ตอนประกาศค่าก็ได้ เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Kitty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ก็จะได้ค่าตามที่กำหนดคือ &lt;code&gt;cat.Name = "Kitty"&lt;/code&gt; และ &lt;code&gt;cat.Weight = 2&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Class with methods
&lt;/h1&gt;

&lt;p&gt;ตอนนี้เราสามารถสร้างสิ่งที่เหมือนกับ class ที่มี property แล้ว แต่ว่าในโลกของ OOP เนี่ย class ไม่ได้มีแค่ property แต่ยังมี method ด้วยใช่มั้ย?&lt;/p&gt;

&lt;p&gt;ใน Go เราสามารถสร้าง method ให้กับ struct ได้โดยไม่ได้เขียนลงใน struct เลย แต่ใช้การการผูกฟังก์ชั่นเข้าไปโต้งๆ ทีหลัง ซึ่งคำว่า "ผูกโต้งๆ" อาศัยสิ่งที่เรียกว่า receiver&lt;/p&gt;

&lt;p&gt;ตัวอย่างเช่น เราจะเติม method &lt;code&gt;Eat()&lt;/code&gt; ให้กับ &lt;code&gt;Animal&lt;/code&gt; ได้แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Eat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สังเกตว่ารูปแบบการเขียนฟังก์ชั่นจะมีบางอย่างเพิ่มเข้ามา คือ &lt;code&gt;(a *Animal)&lt;/code&gt; สิ่งนี้แหละที่เรียกว่า receiver โดย &lt;code&gt;a&lt;/code&gt; คือ receiver variable ส่วน &lt;code&gt;*Animal&lt;/code&gt; เป็น receiver type สังเกตว่าจะไม่มีการใช้คีย์เวิร์ด this เหมือนภาษาอื่น แต่จะใช้ receiver อ้างอิงไปเลย&lt;/p&gt;

&lt;p&gt;ลองเขียนโค้ดทดสอบดู&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Kitty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Eat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Weight: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จะได้ค่า &lt;code&gt;a.Weight = 3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;แล้วทีนี้อยากให้มี method อีกสักกี่อันก็แค่เขียนฟังก์ชั่นโดยผูก receiver เข้าไป&lt;/p&gt;

&lt;p&gt;ข้อดีของการเขียนลักษณะนี้คือทำให้สามารถเติม method เข้าไปได้โดย struct ไม่บวม (อยู่คนละไฟล์ได้) และการใช้ชื่อตัวแปร receiver แทน &lt;code&gt;this&lt;/code&gt; ทำให้ refactor โค้ดจาก function ธรรมดามาเป็น method ได้ง่ายๆ โดยไม่ต้องแก้ชื่อตัวแปรเป็น &lt;code&gt;this&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;เสริมอีกนิดว่า receiver มี 2 แบบคือ value receiver กับ pointer receiver สำหรับในตัวอย่างเราใช้ pointer receiver ซึ่งคือแบบนี้ &lt;code&gt;(a *Animal)&lt;/code&gt; เพราะต้องการแก้ไขข้อมูล เวลาใช้ value receiver ซึ่งคือแบบนี้ &lt;code&gt;(a Animal)&lt;/code&gt; เราจะไม่สามารถแก้ไขข้อมูลได้&lt;/p&gt;

&lt;p&gt;เช่น ถ้าแก้โค้ดของ method &lt;code&gt;Eat()&lt;/code&gt; เป็นแบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// การใช้ value receiver จะไม่สามารถแก้ไขข้อมูลได้&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Eat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ผลที่ได้คือคือค่าของ &lt;code&gt;a.Weight&lt;/code&gt; จะไม่เปลี่ยน&lt;/p&gt;

&lt;h1&gt;
  
  
  Inheritance (หรือจริงๆ คือ Composition)
&lt;/h1&gt;

&lt;p&gt;การ "สืบทอด" ใน Go ก็แตกต่างจากภาษาอื่นที่ใช้คีย์เวิร์ด extends แต่ Go ออกแบบมาให้ "Composition over Inheritance" จึงใช้การ "ฝัง" (embedding) struct ซ้อนเข้าไปข้างใน เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Animal&lt;/span&gt;
  &lt;span class="n"&gt;SlaveName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Meow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Meow"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราจะได้ &lt;code&gt;Cat&lt;/code&gt; ที่มี property และ method ของ &lt;code&gt;Animal&lt;/code&gt; ติดมาด้วยทันที&lt;br&gt;
ทดสอบด้วยการเขียนโค้ดตามด้านล่างนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Eat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Name: %v, Weight: %v, SlaveName: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SlaveName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;โค้ดจะไม่พัง และจะได้ผลลัพธ์เป็น &lt;code&gt;Name:, Weight:1, SlaveName:&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Name&lt;/code&gt; เป็นสตริงว่าง จาก zero value&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Weight&lt;/code&gt; เป็น 1 เนื่องจากมีการสั่ง &lt;code&gt;cat.Eat()&lt;/code&gt; ทำการเพิ่มค่าจาก zero value ครั้งนึง&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SlaveName&lt;/code&gt; เป็นสตริงว่างจาก zero value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;แล้วถ้าเกิดเราต้องการใส่ค่าเริ่มต้นให้กับ &lt;code&gt;cat&lt;/code&gt; ล่ะ? ในเมื่อเราสามารถเรียก property ที่มาจาก &lt;code&gt;Animal&lt;/code&gt; ได้ตรงๆ งั้นเราลองใส่ &lt;code&gt;Weight&lt;/code&gt; เป็น 2 ให้กับ &lt;code&gt;cat&lt;/code&gt; ดูหน่อย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SlaveName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Jack"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ปรากฏว่าเขียนแบบนี้จะเจอ syntax error…&lt;/p&gt;

&lt;p&gt;นี่เป็นเรื่องที่เราเจอตอนลองเขียนครั้งแรก แล้วก็งงว่าจะใส่ค่าเริ่มต้นให้มันได้ยังไง แล้วก็ค้นพบว่า วิธีที่ถูกต้องคือ ต้องระบุชื่อ struct ที่ embed มาด้วย!&lt;/p&gt;

&lt;p&gt;เนื่องจากตอนประกาศ struct เราใส่ &lt;code&gt;Animal&lt;/code&gt; เข้าไป ตอนเซ็ตค่าเริ่มต้นเราก็ต้องระบุ &lt;code&gt;Animal&lt;/code&gt; เหมือนกัน แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;SlaveName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Jack"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ทีนี้ถ้าลองสั่ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Eat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Name: %v, Weight: %v, SlaveName: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SlaveName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราจะได้ผลลัพธ์ &lt;code&gt;Name:, Weight:3, SlaveName:Jack&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Name&lt;/code&gt; ยังเป็นสตริงว่างเพราะไม่ได้กำหนดค่า&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Weight&lt;/code&gt; เป็น 3 เนื่องจากค่าเริ่มต้นถูกเซ็ตเป็น 2&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SlaveName&lt;/code&gt; ได้ค่า Jack ที่เซ็ตเข้าไป&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ตอนที่ดึงค่าออกมาจาก field หรือเรียก method สามารถเรียกได้เลยตรงๆ แต่ตอนประกาศค่าต้องระบุชื่อ struct ที่ embed มาเสมอ&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;สำหรับ OOP ใน Go คร่าวๆ ก็ประมาณนี้ค่ะ&lt;/p&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>oop</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
