เราอาศัยอยู่ในยุคที่เทคโนโลยียังคงดำเนินต่อไปอย่างรุดหน้า ในฐานะที่เป็นนักพัฒนาในศตวรรษที่ 21 เราตระหนักอย่างยิ่งว่าจะต้องเรียนรู้ภาษาโค้ดดิ้งใหม่ๆ ให้ทันต่อการเปลี่ยนแปลงที่เกิดขึ้นอย่างรวดเร็ว และถือเป็นการเพิ่มความหลากหลายในทักษะงาน เพิ่มสมรรถนะ และทำให้สายงานของเรามีความก้าวหน้าด้วย
ด้วยเหตุนี้ สิ่งที่สำคัญที่สุดสำหรับนักพัฒนานั้น ไม่ใช่การพยายามที่จะเอาภาษาโค้ดดิ้งหลายๆ ภาษามายัดรวมกันไว้ให้ได้มากมายเท่าที่จะโชว์ได้ แต่ว่าต้องสามารถมองที่ปัญหาและใช้ทักษะที่เหมาะสมเพื่อแก้ไขปัญหานั้นๆ ได้อย่างสอดคล้อง เมื่อคุณต้องพิจารณาปัจจัยต่างๆ เช่น ประสิทธิภาพของตัวแอปพลิเคชั่นเอง ประโยชน์ในการใช้สอย และ ประสิทธิผลของงานที่ได้ ความรู้ที่ได้เรียนเพิ่มเติมไว้นี้เองคือสิ่งที่จะเข้ามาช่วยเสริมแรงได้
หลังจากที่ได้ใช้เวลาพัฒนางานด้วยภาษา JavaScript และ TypeScript ไปสักระยะ ผมก็รู้สึกว่าตนเองต้องก้าวต่อไปเพื่อขยายขอบเขตความรู้ของตนเองให้กว้างมากขึ้น จึงได้เริ่มจับการเรียนรู้เรื่อง Go มากขึ้น ในขณะเดียวกัน การได้โอกาสใช้งานสิ่งนี้ทำให้ฉันเองได้มีแรงกระตุ้นให้สำรวจเครื่องมือใหม่นี้ และแบ่งปันประสบการณ์กับคนรอบข้างด้วย
ก่อนที่เราจะเริ่มต้นกันวันนี้ ของชี้แจงก่อนว่า บทความที่เขียนขึ้นนี้ไม่ใช่ประสบการณ์ที่จะให้ข้อมูลได้ทั้งหมดครบถ้วน และจะครอบคลุมไปหมดเสียทุกเรื่องเกี่ยวกับ Go หากคุณมีความสนใจในรายละเอียดของ Go คุณสามารถค้นหาข้อมูลเพิ่มเติมได้ที่ส่วนท้ายของบทความนี้
หากไม่มีอะไรต้องกังวลแล้ว เราก็มาเริ่มแบ่งปันประสบการณ์กันดีกว่าค่ะ
เกี่ยวกับ Go
Go คือภาษาโปรแกรมมิ่งแบบที่เป็น Strong & Statically typed ที่หมายถึงว่าแต่ละตัวแปรก็จะมีประเภท (type) ของตัวเองที่ไม่สามารถเปลี่ยนแปลงได้เมื่อเวลาผ่านไปนานเท่าไรก็ตาม และต้องได้รับการนิยามให้ชัดเจน ณ เวลาที่ทำการ compile สิ่งนี้จะช่วยให้เราสามารถเก็บบันทึก errors ณ เวลาที่กำลังทำ compilation time ได้อย่างง่ายดาย
เนื่องจาก Go ถูกพัฒนาโดย Google เราจึงมั่นใจได้ว่าได้รับการสนับสนุนจาก community ที่มีสมาชิกอีกจำนวนมากร่วมใช้ภาษานี้ด้วยกัน ในแง่ของการดูทิศทางของการขอให้พัฒนาเพิ่มเติมแล้ว (ดูจากสถิติที่ผ่านมา) Go ได้รับการพัฒนาตามเสียงเรียกร้องของสมาชิกจนได้รับความนิยมติดอันดับ Top 5 ภายในสี่ปีเลยทีเดียว
จากประวัติของ Go แล้ว ทีมงานของ Google ได้เคยเลือกระหว่างการเร่งพัฒนาเพื่อประสิทธิภาพการทำ compilation ; ประสิทธิภาพการทำ execution และความง่ายของการโปรแกรมมิ่ง ทั้งสามเรื่องนี้ไม่เคยอยู่ในสายตาของภาษาโค้ดดิ้งใดๆ มาก่อนเลย ดังนั้น Go จึงถูกสร้างขึ้นมาเพื่อเป็นที่สุดเหนือจากภาษาอื่นๆ และถูกออกแบบมาเพื่อการนำไปใช้ให้เห็นผลจริงโดยเฉพาะ ซึ่งข้อดีที่เกิดขึ้นนั้น (ตัวอย่าง) ได้แก่เรื่องต่อไปนี้ :
- การทำให้ Go มีความง่ายและชัดเจน: Go ยังไม่เคยได้รับการเปลี่ยนแปลงมากนักในรอบสิบปีที่ผ่านมา สิ่งนี้ทำให้โปรแกรมเมอร์มีโอกาสเรียนรู้ Go syntax ได้ง่ายขึ้น เพราะมันไม่ได้แปลกตาไปกว่าเมื่อทศวรรษก่อนหน้านี้ ความเรียบง่ายที่ยังเบสิคเกินไปยังจำกัดจำนวนของวิธีในการเขียนโค้ดให้หลากหลายไปได้ไม่มาเท่าไหร่นัก ดังนั้นจึงมักเป็นเรื่องง่ายที่จะเข้าใจได้อย่างทีละส่วนได้
- ความสามารถในการรัน Go code ได้อย่างรวดเร็ว: การทำ compilation นั้นเป้นไปได้เร็วขึ้นนับแต่ Go ได้รับการออกแบบมาเพื่อยอมให้ compiler สามารถที่จะ compile ส่วนของ dependency ต่างๆ ได้อย่างรวดเร็ว
- การรวบรวม Garbage collection: สิ่งนี้มาพร้อมแบบฟรีๆ กับ Go และ remove ตัว memory instance ที่ไม่มีการใช้งานออกไปแล้วได้ด้วย Go ยังมีประสิทธิภาพเพราะมันดูแล memory type ที่ซึ่งตัดสินใจว่า Heap หรือ Stack จะต้องถูก allocated ไปยังตัวโครงสร้างหรือไม่
Slice ที่น่าสนใจของ Go
ในขณะที่ฉันกำลังเรียนรู้ Go ฉันได้พบกับ slice บางอย่างที่น่าสนใจ (ก็เขียนแบบเล่นคำอ่ะนะคะ) ที่ซึ่งทำตัวได้แตกต่างจาก JavaScript และตอนนี้ที่เรามีการได้แนะนำเบื้องต้นกันแล้ว ลองมามองที่สิ่งที่จะพูดต่อไปกันในบทความนี้กันดีกว่า:
- ค่า Zero values ใน Go
- Go ตีความอ้างอิง type ของตัวแปร initialised variables และจากนั้นทำการ initialise ตัวแปรไปในหลากหลายรูปแบบ
- การส่งค่า return values แบบ multiple values และแบบ named return parameters
- ชื่อที่ถูก Exported และ unexported ใน Go
- ประเภทของ Composite types (Arrays, Slices, Maps)
- ส่วนติดต่ออินเทอร์เฟส
- แนวคิดของ pointer
1. ค่า Zero values ใน Go
ที่แตกต่างจาก JavaScript ที่มีตัวแปรแบบที่ declared และ uninitialised ที่ปกติแล้วจะได้รับค่า value แบบ undefined ส่วนค่าตัวแปรใน Go นั้นเป็นค่าที่ declared โดยปราศจาก initialised value ที่ชัดเจน และจะได้รับค่า default เป็น zero value
2. Go ตีความอ้างอิง type ของตัวแปร initialised variables และจากนั้นทำการ initialise ตัวแปรไปในหลากหลายรูปแบบ
a. Go สามารถสรุปอ้างอิง data type เมื่อได้รับค่า value assignment ถึงแม้ว่าจะมันจะเป็นภาษาแบบ statistically typed language ก็ตาม ดังนั้น เราไม่จำเป็นต้องระบุ type ณ เวลาของการประกาศ declaration (หมายเหตุ: ฉันใช้ package ที่สะท้อนมาให้เห็นนี้เพื่อระบุ type ของ value เท่านั้น)
รันตัวอย่างได้ได้ที่นี่
B. Go variables สามารถถูก initialised ในหลากหลายรูปแบบ:
รันตัวอย่างได้ได้ที่นี่
3. การให้ค่า return values แบบ multiple และค่า return parameter แบบ named
a ฟังก์ชั่นสามารคืนค่าออกมาเป็นผลลัพธ์ใดๆ ก็ได้จำนวนหนึ่ง มันจึงมักจะเป็เคสสำหรับฟังก์ชั่นเพื่อให้คืนค่าทั้งผลลัพธ์ และค่า error values
รันตัวอย่างได้ที่นี่
b ค่า return parameters แบบ named
เราสามารเรียกชื่อ return variables ใน Go functions definition ได้อย่างชัดเจน ทำให้ลดความจำเป็นที่จะต้อง mention ค่า variable name อีกครั้งในข้อความ return statement ข้อดีนี้ช่วยให้ความสะดวกสบายในการอ่านนนั้นเข้าใจได้ง่ายขึ้น เนื่องจากคนทำงานหรือใครก็ได้สามารถเรียนรู้เกี่ยวกับ return parameters ต่างๆ เมื่อกำลังอ่านค่า function signature อยู่ เทคนิคนี้แนะนำให้ใช้เฉพาะ function signature แบบสั้นสั้นๆ เท่านั้น
รันตัวอย่างที่นี่
4 ชื่อที่ถูก exported และ unexported ใน Go
เมื่อเราได้ import ตัว package เข้ามา เราจะสามารเข้าถึงชื่อที่ถูก exported ออกมาไว้ได้ ปกติแล้ว ในรูปแบบของ type, function หรือ variable ค่าชื่อ exported name จะต้องเริ่มต้นด้วยตัวอักษรใหญ่ (Capital Letter) เพื่อให้สามารถมองเห็นได้นอกเขตของ Package
รันตัวอย่างที่นี่
5 ประเภทแบบ composite type
ในส่วนของ Go นั้น array คือลำดับที่มีการจัดเรียงของ element ที่จัดไว้ว่าอยู่ใน type เดียวกัน เมื่อ array หนึ่งได้จัดแจกขนาดไว้เป็นสัดส่วนแล้ว เราจะไม่สามารถเแลี่ยนแปลงพวกมันได้อีกต่อไป
รันตัวอย่างที่นี่
Slice นั้นสร้างบน array และ slice มี index และ length แต่ที่ต่างจาก array พวกมันจะปรับขนาดตัวเองได้แบบ dynamic และดังนั้นจึงทำให้เกิดความคล่องตัวมากกว่า Slice มีความใกล้เคียงกับสิ่งที่เรารู้จักกันในชื่อของ array ใน JavaScript นั่นเอง
รันตัวอย่างที่นี่
Struct คือกลุ่มของ field ที่กำหนดรูปแบบไว้แล้วโดย uset และสามารถเปลี่ยนแปลงได้ ฉันเองอยากจะมองว่า struct เหล่านี้เป็นเหมือน object template สำหรับ data record (เช่น attribute ที่แตกต่างกันเพื่อเป็นตัวแทนของ employee profile)
รันตัวอย่างที่นี่
6. ส่วนติดต่ออินเทอร์เฟซ
ส่วนติดต่ออินเทอร์เฟซใน Go คือกลุ่มของ type collection ที่ระบุพบในกลุ่มของ methods ต่างๆ เราสามารถคิดถึงมันว่าเป็นการนิยาม set ของพฤติกรรมสำหรับชุด objects ที่คล้ายคลึงกัน และเรียกดูส่วนติดต่ออินเทอร์เฟซในลักษณะที่จะทำให้เกิดเป็น polymorphism ขึ้นมาได้
ตัวอย่างเช่น ส่วนติดต่ออินเทอร์เฟซสำหรับพนักงาน (Employee) นั้นควรจะต้องมี method ที่เรียกว่า jobTitle
ในตอนนี้ที่เราได้ส่วนติดต่อ Employee interface แล้ว และลองมาดูที่ตัวอย่างของ type of employee สักประเภทหนึ่งเพื่อเป็นตัวอย่าง ลองจินตนาการว่าเรามี job title ที่แตกต่างกันสำหรับพนักงานต่างๆ ในแต่ละแผนกที่แตกต่างกัน (เราเรียกกันว่าเป็น hive ใน PALO IT) ทั้ง digitalhive และ agilehive type จะช่วยให้ส่วนติดต่อ Employee interface มีความน่าพึงพอใจในการใช้งาน เนื่องจากถูกสร้างขึ้นมาจาก employees ที่มี different job titles ที่แตกต่างกัน
ในขณะที่เราต้องการ type ที่มีความแตกต่างกัน (คือมีทั้งแบบ digitalhive และ agilehive) เพื่อตั้งให้แสดงพฤติกรรมแบบที่เป็นไปในทิศทางเดียวกันกับ method ที่ถูกเรียกไว้แล้วว่าชื่อ jobTitle จากนั้นเราจะใช้ jobTitle method นี้ให้มีความเป็นอิสระจาก type อื่นๆ กับส่วนติดต่ออินเทอร์เฟซนั่นเอง
รันตัวอย่างที่นี่
7 แนวคิดเรื่อง Pointers
เพื่อการทำความเข้าใจเรื่อง pointers เราจำเป็นต้องเข้าใจก่อนว่าเกิดอะไรขึ้นเมื่อเรา assign ข้อมูลไปที่ตัวแปร variable หนึ่ง คือเมื่อข้อมูลได้รับการจัดเก็บ เราได้จัดเก็บมันไว้ใน memory ณ ที่อยู่ หรือ address หนึ่ง ที่อยู่ในการเก็บ memory นี้เป็น address ที่นำเสนอโดยรูปแบบลักษณะ hexadecimal ส่วนในการที่จะเข้าถึงข้อมูลที่ถูกเก็บไว้ เราจำเป็นที่จะต้องรู้ว่า address นี้คืออะไร ค่าตัวแปรนี้จะให้เรามี memory location ที่บอกตำแหน่งของข้อมูลที่ถูกจัดเก็บไว้ ในตอนนี้ pointer คือค่า variable แบบพิเศษแต่ว่สมันจะเก็บข้อมูล memory address สำหรับ variable อื่นๆ ต่อไปได้
รันตัวอย่างที่นี่
ในตอนนี้ก็มาถึงจุดที่เราต้องเข้าใจว่า pointer นั้นทำงานอย่างไร และมันคืออะไร และเมื่อไรที่เราจะต้องใช้ pointer บ้าง
เนื่องจาก struct คือทางผ่านโดยอาศัย value type ฉันจะใช้มันเพื่ออธิบายวิธีการใช้ pointer ต่อไป เมื่อ struct ถูกส่งต่อไปยัง function ต่างๆ โดย value มันจึงหมายถึงว่าชุด copy ของ struct จะถูกสร้างเมื่อมีการส่งผ่านไปยัง function สิ่งนี้ประยุกต์ใช้ได้กับส่วนที่เหลือของการส่งผ่านแบบ pass by value type ด้วยเช่นกัน
ปกติแล้ว เราจำเป็นต้องส่งผ่าน struct by reference เมื่อไรก็ตามที่เราต้องการที่จะสร้างการเปลี่ยนแปลงให้กับชุด copy ที่กำลังส่งผ่านอยู่ (หมายเหตุ: ในปกติแล้ว บางคำแนะนำเกี่ยวกับ Go แนะนำว่า การส่งผ่าน small struct ในฐานะ value นั้น เว้นแต่ว่า function นั้นๆ ที่เรากพลังเรียกนั้น จำเป็นต้องแก้ไขมันหรือไม่)
ต่อไปนี้คือตัวอย่างบางประการของ value type ที่เรามักจะใช้ pointer เพื่อเปลี่ยนแปลงสิ่งต่างๆ เมื่อต้องส่งผ่าน function หนึ่งๆ ไป:
การทบทวน
ในการสรุปสิ่งที่ได้เล่ามาทั้งหมด การเรียนรู้ภาษาใหม่ช่วยให้นักพัฒนาปรับปรุงทักษะด้านการแก้ไขปัญหา (problem-solving skills) เนื่องจากมันจะขยายกระบวนการคิดให้กว้างออกไปได้ จึงเป็นเรื่องที่เป็นประโยชน์ที่จะได้คุ้นเคยกับเครื่องมือใหม่ เพราะปัญหาของแอปพลิเคชั่นนั้นควรได้รับการแก้ไขปัญหาด้วยกระบวนการใหม่ๆ บ้าง จากที่ได้พูดมา ฉันหวังว่าการแบ่งปันเรื่องราวของ Go slices เหล่านี้ที่ฉันพบว่าน่าสนใจและแตกต่างจาก JavaScript มากมาย คุณน่าจะตื่นตาตื่นใจมากพอที่จะลองหยิบยกมาเล่นดูเองบ้างสักวัน
ในความคิดของฉัน เวลาที่ใช้ในการเรียนรู้ Go นั้นต้องอาศัยเวลาที่นานและเรียนจนลึกพอสมควร เพราะความแพร่หลายในการใช้งานแตกต่างสถานการณ์และมีความแตกต่างจาก JavaScript โดยสิ้นเชิง อย่างไรก็ตาม ประโยชน์ที่คาดว่าน่าจะเกิดนั้นคาดว่ามีมากมายมหาศาล อย่างเช่นการที่ Google สร้าง Go ขึ้นมาเพื่อแก้ไขปัญหาด้าน scalability ซึ่งมันได้ช่วยนักพัฒนาอย่างมากที่ต้องจัดการกับ activity ในปริมาณและโตขึ้นตลอดเวลาที่มีจำนวนมากแต่ว่าคาดการณ์ได้ ในขณะที่ Go มีการสนับสนุนสำหรับ concurrency (Goroutines) ทีมของคุณสามารถทำงานร่วมกันกับหลายๆ สิ่งพร้อมกันได้แบบต่อเนื่องและแบบที่ไม่ต้องพึ่งพาสิ่งอื่นใดอีก
ยังมีข้อมูลพร้อมให้อ่านอีกมากมายภายนอกนั้นที่ช่วยให้คุณได้เริ่มลองเล่น Go ได้ด้วยตนเอง (TODO คือแอปะลิเคชั่นที่ดีที่สุดในการเริ่มสร้างและประยุกต์ใช้ความรู้นี้)
ต่อไปนี้คือทรัพยากรเพิ่มเติมที่ช่วยให้ฉันเรียนรู้เพิ่มเติมได้อย่างมาก:
เอกสารเกี่ยวกับ Go
Go และตัวอย่าง
เรียนรู้การใช้งานการเขียนโปรแกรมมิ่ง Go - เอกสาร Tutorial สำหรับ Beginner
Go Playground - code สำหรับการทดสอบ Proof of Concept ก่อนการใช้งาน