ภาษา Go ตอน 2 Syntax

Chaiyarin Niamsuwan
odds.team
Published in
6 min readAug 19, 2018

หลังจากที่ ตอนที่ 1 ที่ผ่านมา เราได้เรียนรู้วิธีการ ติดตั้ง และ สามารถ Run Hello World ได้แล้ว ใครยังไม่ได้อ่าน สามารถไปอ่านได้จาก Link ข้างล่างนี้ครับ

เกริ่นก่อนเข้าเรื่อง

ในตอนที่ 2 นี้ ผมจะพาไปทำความรู้จักกับ Syntax ต่างๆ เบื้องต้น สำหรับเขียนโปรแกรมด้วย ภาษา Go

โดยจะพาไปรู้จักกับ

  • รู้จักกับ The Go Playground
  • ข้อตกลงในการตั้งชื่อ (Naming Convention)
  • การประกาศตัวแปร
  • การสร้าง Function
  • การใช้ Loop ประเภทต่าง ๆ
  • การใช้เงื่อนไข (IF ELSE)
  • การใช้งาน Array
  • การใช้งาน Slice
  • การใช้ Map

ประมาณนี้ เมื่อเราได้รู้ประมาณนี้ เราก็จะพอมีพื้นฐานไปต่อยอดทำสิ่ง ๆ ต่างๆ ได้แล้วครับ โอเคไม่รอช้าเรามาเริ่มกันไปทีละตัวเลยดีกว่า

รู้จักกับ The Go Playground

ก่อนจะไปลุยกันเต็มๆ ผมขอแนะนำให้ทุกคนรู้จักเว็บนึง มันคือเว็บสำหรับ Compile ภาษา Go แบบ Online

ทำให้เราไม่ได้ต้องไป ติดตั้ง ภาษา Go ในเครื่อง คือสามารถ Compile ได้เลยผ่านเว็บไม่ต้องไป ใช้คำสั่ง go run ในเครื่องอะไรให้วุ่นวาย เข้าไปที่ Link นี้เลยครับ

https://play.golang.org/

หน้าจอ Web ของ The Go Playground เอาไว้ Compile ภาษา Go Online

หลังจากนี้ก็เอาแต่หัวข้อในนี้ run ผ่านเว็บนี้ได้เลย ต้องลองลงมือทำเลยครับจะได้คุ้นชิน ปะลุย

ข้อตกลงในการตั้งชื่อ (Naming Convention)

คืองี้ การตั้งชื่อในภาษา Go นั้นเค้ามี Concept ว่า สั้น กระชับ มองแล้วรู้เรื่องเลยว่าหมายถึงอะไร

และ ไม่ควรที่จะตั้งชื่อให้มันตรงกับตัว Source Code ของภาษา Go มันจะทำให้ซ้ำกับระบบและ Error ได้ เช่นพวก if, else, base64, int อะไรพวกนี้ห้ามตั้ง พูดง่ายๆ อย่าไปตั้งชื่อไฟล์ ชื่อตัวแปรอะไรต่างๆ ซ้ำกับ (Reserved word)

วิธีการตั้งชื่อไฟล์

การตั้งชื่อไฟล์ ของภาษา Go เราจะตั้งชื่อไฟล์ในรูปแบบ snake_case เช่น calculate_grade.go, calendar_mapping.go

วิธีการตั้งชื่อตัวแปร (Variable) และ ฟังก์ชัน (Function)

การตั้งชื่อตัวแปร ของภาษา Go นั้นเราจะตั้งชื่อในรูปแบบ camelCase เช่น memberLists, firstName, lastName

การประกาศตัวแปร

การประกาศตัวแปรในภาษา Go นั้นมีหลายท่ามาก เดี๋ยวผมจะพาไปในลุยในทุกๆแบบที่พอจะจำได้

แบบที่ 1

var a, b, c bool;

แบบนี้คือแบบเต็มๆ จาก Code ที่เห็น คือ ประกาศตัวเป็น a, b, c ให้เป็น Type Boolean ทั้ง 3 ตัวเลย หรือ แบบนี้

var a, b, c string;

ก็คือ ประกาศให้ตัวแปร a, b, c ให้เป็น Type String ทั้ง 3 ตัวเลย

แบบที่ 2

var a, b, c bool = false, false, true;

การประกาศแบบนี้ หมายความว่า เราสามารถใส่ค่าตัวแปรไปในการประกาศได้เลย Go จะรู้เองว่า ค่าของแต่ละตัวจะเอาไปใส่ตรงไหน

ดังนั้นจาก Code นี้ จะทำให้ ตัวแปร a มีค่า เป็น false และ b มีค่าเป็น false และ c มีค่าเป็น true

แบบที่ 3

var a, b, c = false, 10, "เรียนภาษา Go";

การประกาศแบบนี้เราจะสังเกตเห็นว่า มันไม่มี Type บอก ว่าเราประกาศตัวแปรเป็นประเภทอะไร

แต่ตัวแปรเหล่านี้ จะถูกกำหนดค่า Type ต่างๆ ตาม ค่าที่เรานำไปใส่ตัวแปร ดังนั้น ตัวแปรต่างๆ จะมี Type และ ค่าดังนี้

a มีค่า เป็น false มี Type เป็น Boolean

b มีค่า เป็น 10 มี Type เป็น Integer

c มีค่า เป็น “เรียนภาษา Go”มี Type เป็น String

แบบที่ 4

a, b, c := false, 10, "เรียนภาษา Go";

มาถึงการประกาศตัวแปร แบบที่ผมคิดว่าเค้าใช้บ่อยสุดกันละ คือการประกาศ แบบที่ 4 นี่หละ

จาก Code จะสังเกตว่า มีการตัด var ออกไป และก็ ไม่มี Type แต่สิ่งที่เพิ่มขึ้นมาคือ สัญลักษณ์ “:” หรือ เรียกง่าย ๆ ว่า “โคลอน”

ซึ่งจะมาใช้เป็นการ ประกาศแบบตัวแปร แบบ Shorthand ครับ

การสร้าง Function

การสร้าง Function ในภาษา Go นั้นง่าย มากๆ เลยครับ เราจะไล่ไปทีละ Step by Step โดยเริ่มจาก

แบบที่ 1 Basic

นี่คือหน้าตา Function แบบ ไม่มีการ Return ค่า และ รับ Parameter เลยครับ และทำงานแค่ แสดง คำว่า “กรุงเทพ” ใน Console ตอนสั่ง Run เท่านั้น

func printSchoolAddress() {     println("กรุงเทพ");}

แบบที่ 2 มีการรับ Parameter

การใส่ Parameter นั้น เราจะประกาศ Type ของ Parameter นั้นไว้ข้างขวา และ ชื่อ Parameter ไว้ด้านซ้าย

func printSchoolAddress(schoolAddress string) {     println(schoolAddress);}

แบบที่ 3 มีการ Return Value

การ Return Value ออกจาก Function นั้น เราจะประกาศ Type ของ สิ่งที่จะ Return ต่อจาก วงเล็บของ Function เวลาเราจะให้งาน เราก็หาตัวแปร มารับค่าจาก Function นี้ เป็นอันจบ

[ประกาศ Function แบบ มีการ Return ค่า]func getSchoolAddress() string {     return "กรุงเทพ";}[การรับค่า Function ที่มีการ Return]schoolAddress := getSchoolAddress();

แบบที่ 4 มีการ Return Value หลายค่า

สำหรับผมแล้ว เรื่องนี้เป็นเรื่องที่หน้าตื่นตาตื่นใจมาก ในภาษา Go ปกติเราจะเห็นแค่ว่ามีการ Return Value แค่ค่าเดียว

แต่ในภาษา Go นั้น เราสามารถ Return Value ได้หลายค่า ด้วย แต่ละค่าที่ Return คนละ Type ก็ได้เช่นกัน ด้วยการเขียน Function แบบนี้

[ประกาศ Function แบบ มีการ Return หลายค่า]func getSchoolAddress() (int, string) {     code := 1993;
address := "กรุงเทพ";
return code, address;
}[การรับค่า Function ที่มีการ Return หลายค่า]resultCode, resultAddress := getSchoolAddress();

การ Return หลายค่า จะเห็นว่ามันไม่ยากเลย เพียงแค่ใส่วงเล็บหลัง วงเล็บของ Function เท่านั้นเอง แค่นี้เราก็จะสามารถ Return หลายค่าและนำตัวแปรมารับไปใช้งานได้แล้วครับ

การใช้ Loop ประเภทต่างๆ

ขอบอกเลยว่า ทุกๆ Loop ประเภทต่างๆ ที่ใช้ใน ภาษา Go ไม่ว่าจะเป็น

  • For Loop
  • Do While Loop
  • While Loop

นั้นล้วนแล้วแต่ ใช้ ตัวด้วยเลย ก็คือ For นั่นเอง ปะ เรามาเริ่มแบบที่ 1 กัน

แบบที่ 1 For Loop

[For Loop]for i:= 1; i< 9; i++ {   println(i);}[ผลลัพธ์ที่ได้จากการ Run Loop นี้]1, 2, 3, 4, 5, 6, 7, 8

อธิบายก็คือ เป็นการกำหนดว่าตัวแปร i ให้มีค่าเท่ากับ 1 และวนไป เรื่อยๆ จนจบเงื่อนไข แบบ Basic ปกติเลยครับ

แบบที่ 2 Do While Loop

[Do While Loop]i := 1;for {    if i==2 {       println(i);
break;
}
i++;
}[ผลลัพธ์ที่ได้จากการ Run Loop นี้]2

อธิบายก็คือ Loop นี้มันเป็นฟิลลิ่งเหมือน Loop ที่ไม่มีวันจบสิ้น (Infinity Loop) และเราก็กำหนดเงื่อนไข เพื่อให้มันออก Loop ได้

ดังนั้น ลักษณะ ทำก่อน และ ออก Loop ทีหลังแบบนี้ ก็คือ Do While Loop นั่นเอง

แบบที่ 3 While Loop

[While Loop]i := 1;for i <= 5 {    fmt.Println(i);    i = i + 1;}[ผลลัพธ์ที่ได้จากการ Run Loop นี้]1, 2, 3, 4, 5

ก็นั้นหละครับแบบที่บอกไป ตอนแรกของหัวข้อ Loop นี้ ภาษา Go นั้น Loop ต่างๆ จะมี Keyword ในการใช้ว่า For ทั้งหมดนั่นเอง

การใช้เงื่อนไข (IF ELSE Condition)

หลักๆแล้ว การใช้งานเงื่อนไขของภาษาก็ แบ่งออกเป็น สองแบบหลักๆ ด้วยกัน

แบบที่ 1 if else แบบปกติ

[if else แบบปกติ]x := 10;if x < 10 {   println("x มีค่าน้อยกว่า 10");} else {   println("x มีค่ามากว่า หรือ เท่ากับ 10");}[if else if]x := 10;if x < 10 {   println("x มีค่าน้อยกว่า 10");} else if x == 10 {   println("x มีค่าเท่ากับ 10");} else {   println("x มีค่ามากกว่า 10");}

จากตัวอย่างของ Code จะเห็นว่าเงื่อนไขตรง if จะไม่มี วงเล็บ แค่นั้นเลยครับ สำหรับการใช้ If Else แบบ พื้นฐาน

แบบที่ 2 if else แบบ ทำ Process บางอย่างก่อน Check เงื่อนไข

คืองี้ปกติแล้ว เวลาเราจะ Process ค่าอะไรบางอย่างก่อน เข้าเงื่อนไข If นั้นเราจะต้องทำแบบนี้ เช่น ๆ

i := 2;
j := 3;
k := 0;
k = i + j;if k == 5 { println("k มีค่าเท่ากับ 5");}

จะเห็นว่า อันนี้คือท่าพื้นฐาน แต่ Go นั้นสามารถ Process ค่าก่อนเข้าเงื่อนไขแบบนี้ได้

i := 2;
j := 3;
k := 0;
if k = i + j; k == 5 { println("k มีค่าเท่ากับ 5");}

นั้นหละครับ If แบบ มี Process ก่อนเข้าเงื่อนไข

การใช้งาน Array

Array ก็คือ Type ของตัวแปรประเภทนึง ที่สามารถระบุขนาดของ กล่องรับข้อมูลภายใน Array ตัวนั้นได้ โดยขนาดที่ว่า นั้นก็คือ Size ที่มันจะเป็นค่าคงที่

โดยการประกาศ Array ในภาษา Go เราจะทำกันแบบนี้

[การประกาศ Array เปล่าๆ ว่างๆ ]var a [5]int; //นี้ก็หมายความว่า a เป็น type int ที่มี Block การใส่ข้อมูล 5 ช่อง[การใส่ค่าใน Array แต่ละช่อง]a[0] = 1;
a[1] = 2;
a[2] = 3;
[ลองแสดงว่า a ทั้งหมดออกมาดูจะได้หน้าตาประมาณนี้][1, 2, 3, 0, 0]

คำถามคือทำไม Index ของ Array ตัวที่ 3 และ 4 มีค่า เท่ากับ 0 นั้นก็เป็นเพราะว่า ค่ามาตราฐานของเมื่อตัวแปรที่เป็นประเภทจำนวนเต็ม (Integer) นั้นว่าง ค่าจะถูก Set Default ไว้ที่ 0

แล้วการประกาศค่า ให้ตัวแปรประเภท Array ตั้งแต่เริ่มต้นเลยหละทำยังไง ทำแบบนี้ครับ

[การประกาศ Array แบบมีค่าเริ่มต้น]var name = [3]string{"Chaiyarin", "Atikom", "Kritsana"};[ลองแสดงว่า name ทั้งหมดออกมาดูจะได้หน้าตาประมาณนี้][Chaiyarin, Atikom, Kritsana]

อีกนิดก่อนจะไปหัวข้อถัดไป การหา Size ของ Array ว่ามีค่าเท่าไหร่ ด้วยคำสั่งนี้ครับ

len(ตัวแปร array);

การใช้งาน Slice

จากการใช้งาน Array จาก หัวข้อด้านบน ก็จะพบว่าเห้ย ก่อนจะใช้ Array นี่ต้องกำหนด “ขนาดของ Array ที่แน่นอน” ล่วงหน้าไว้ก่อน

ซึ่งมันไม่ยืดหยุ่นเอาซะเลย Slice จึงได้เข้ามาแก้ปัญหานี้ คือ Slice จะทำงานได้แทบจะเหมือน Array แต่ว่า ไม่จำเป็นที่จะต้อง “กำหนดขนาดล่วงหน้า”

พูดไปก็ไม่เห็นภาพมาลองลง Code กันครับ

[การประกาศตัวแปร Slice]name := []string{}; [การใส่ค่าใน Slice]name = append(name, "Chaiyarin");
name = append(name, "Atikom");
name = append(name, "Kritsana");
[ลองแสดง name ทั้งหมดออกมาดูจะได้หน้าตาประมาณนี้][Chaiyarin, Atikom, Kritsana]

จาก Code จะเห็นว่า ตอนประกาศตัวแปรประเภท Slice นั้น ไม่จำเป็นต้องมีขนาด กำหนดไว้ก่อนล่วงหน้า

และยังสามารถเพิ่มค่าด้วยคำสั่ง append ได้ โดย สามารถเพิ่มไปเลยยาวๆเลย ไม่จำกัด จำนวนช่องเหมือน Array

หลักการคร่าวๆ ของ Slice จริงๆ แล้ว เบื้องหลังการทำงานมันก็คือ Array นั้นแหละ แต่ลักษณะมันจะทำงานแบบนี้

เมื่อเรา Append ค่าเข้าไปในแต่ละครั้ง มันจะสร้าง Array ตัวใหม่ที่มีช่องข้อมูล เท่ากับตัวล่าสุดที่เพิ่ง Add เข้าไป และ ทำลาย Array ตัวเก่า เท่านั้นเองครับ

อีกนิดก่อนจะไปหัวข้อถัดไป การหา Size ของ Slice ว่ามีค่าเท่าไหร่ ด้วยคำสั่งนี้ครับ

len(ตัวแปร array);

จะสั่งเกตว่าเราสามารถใช้ len() กับ Array และ Slice ได้ เหมือนกันครับผม

การใช้งาน Map

เท้าความนิด เผื่อใครยังไม่รู้จัก Maps จริงๆแล้ว Maps คือ Data Structure รูปแบบหนึ่ง ที่เก็บข้อมูลในลักษณะ Key Value

ดังนั้นการประกาศ Map ในภาษา Go เราจะทำดังนี้

[การประกาศตัวแปร Map]m := make(map[string]int); [การใส่ค่าใน Map]m["chaiyarin"] = 1;
m["atikom"] = 2;
m["kritsana"] = 3;
[ลองแสดงตัวแปร m ทั้งหมดออกมาดูจะได้หน้าตาประมาณนี้]map[chaiyarin:1 atikom:2 kritsana:3]

จาก Code จะเห็นว่า การประกาศตัวแปรแบบ Map นั้นเราจะใช้คำสั่ง make ซึ่งเป็นคำสั่งพื้นฐานที่ Build-in มาในภาษา Go

โดย map[string]int ที่เห็นอยู่ นั้นคือเราบอกว่าให้ Key มี Type เป็น String และ Value มี Type เป็น Integer

หลังจากนั้น เวลาเราจะใส่ค่าก็แค่ใส่ Key อะไรก็ได้ในตัวแปร m และ ก็ตามด้วย Value เท่านี้ก็สามารถใช้ Map ได้แล้ว

Map ยังสามารถ Add ค่าได้ไปเรื่อยๆ แบบไม่มีจำกัดเหมือน Array ด้วยนะครับ

แต่มันยังไม่จบเพียงเท่านี้ Map ยังสามารถ สั่งลบ Key และ Value ที่ไม่ต้องการไปได้อย่างง่ายดาย ตามตัวอย่างนี้

[สมมติว่าค่าใน Map มีดังนี้]map[chaiyarin:1 atikom:2 kritsana:3][เราต้องการลบ key value ของ atikom ออก เราจะใช้คำสั่ง]delete(m, "atikom"); // delete(ตัวแปร map, key ที่ต้องการลบ)

เพียงเท่านี้เราก็จะลบ Key ที่เราไม่ต้องการได้อย่างง่ายดาย

** ในตอน 3 ผมจะพาไปทำความรู้จักกับ เรื่องอื่นๆ ที่ควรรู้อีกเล็กน้อย ในการเขียนภาษา Go เช่น การใช้งาน Defer การใช้งาน Struct ครับ ***

แล้วเจอกันบล็อกหน้า Bye Bye

--

--