Basic goroutine and channel

วันนี้มาเริ่มท่าง่ายๆกับ goroutine และ channel กันก่อน Goroutine เป็นวิธีการเรียก function ให้ทำงานโดยแยกออกจากลำดับการทำงานของ function ที่ไปเรียกใช้งาน ตัวอย่างเช่น เราอยากสร้างฟังก์ชันที่ให้นับทุกๆ 1 วินาที เราจะเขียนโค้ดได้ดังนี้ ลองเล่นผ่าน Go Playground ได้ที่นี่ http://play.golang.org/p/jpM6QcJaKq จะเห็นว่า เราต้องรอการนับแต่ละครั้งจบก่อน ถึงจะนับครั้งต่อไปได้ ทีนี้ถ้าเราต้องการมีตัวนับสองตัวล่ะ ให้ตัวนึงนับทุก 1 วินาที อีกตัวนับทุก 5 วินาที จะเห็นว่าเราไม่สามารถเรียก function สองตัวนี้พร้อมกันได้ วิธีการที่จะทำได้สำหรับ Golang คือเรียกฟังก์ชันให้ทำงานเป็น Goroutine เพื่อให้แยกทำงานอิสระจาก flow การทำงานหลัก วิธีการเรียกฟังก์ชันให้ทำงานแบบ Goroutine คือใช้ keyword ว่า go ข้างหน้าการเรียกฟังก์ชัน เช่น แต่ถ้ารันโค้ดนี้จะพบว่าไม่แสดงอะไรออกมาเลย เพราะอย่างที่บอกไปว่าเมื่อเรียกแบบ Goroutine มันจะแยกอิสระ ทำให้ ณ […]

Continue reading →

Format source code with go fmt

Golang มีเครื่องมือในการ format source code มาให้เพื่อให้โค้ดที่เขียนร่วมกันหลายๆคน หรือ source code ของ library open source ต่างๆ มีรูปแบบเดียวกัน เครื่องมือที่ว่าก็คือ gofmt นั่นเอง วิธีการใช้ ง่ายๆแบบนี้ go fmt main.go เท่านี้ไฟล์ main.go ของเราก็ถูก format ถามรูปแบบของ go fmt แล้ว ถ้าต้องการหลายๆไฟล์ ก็ใช้ go fmt * หรือเอาแบบ ทุกๆ directory ย่อยใช้แบบนี้ได้ go fmt ./… เรื่องการเว้นวรรค หรือ indent สำหรับ go fmt จะใช้ tab ขนาด 8 เสมอ นั่นคือ […]

Continue reading →

วิธี type cast ของ Golang

ในภาษา C และ Java เราสามารถทำการ type casting หรือการแปลง type ง่ายๆได้โดยวิธีนี้ เช่น int a = (int)10.1; char b = (char) 97; จะเห็นว่า เอาชื่อ type ไว้ภายในวงเล็บ แล้วเอาไปไว้ด้านหน้าค่าที่ต้องการแปลง แต่สำหรับ Golang เวลาทำ type cast จะต่างออกไปคือ ใช้ชื่อ type แต่ว่าวงเล็บแทนที่จะครอบ type แต่วงเล็บจะครอบค่าที่ต้องการแปลงเอง เหมือนกับการเรียกฟังก์ชันโดยชื่อ type เป็นฟังก์ชัน นั่นเอง ตัวอย่างเช่น i := int(‘c’) fmt.Println(i) type cast จะใช้บ่อยๆในกรณีที่เราทำการสร้าง type ใหม่ของเราเอง และต้องการแปลงไปแปลงกลับระหว่าง type พื้นฐานที่เราเอามานิยาย type กับ […]

Continue reading →

ทำ forEach เลียนแบบ Java 8

Golang นั้นรองรับการเขียน Anonymous function มาอยู่แล้ว และสามารถใช้ function เป็น value ได้ คือทำตัวเป็น lambda ได้นั่นเอง ตัวอย่างเช่น add := func(x, y int) int { return x+y; } เราสามารถเรียกแบบนี้ได้ result := add(10, 20) และจากที่ผมเขียนบอกไปว่า go นั้นมีการวนซ้ำในรูปแบบเท่านี้ http://golang.in.th/2015/01/08/for-loop/ ถ้าเรามีข้อมูลในลิสต์แบบนี้ members := []string {“John”, “Mike”, “Joe”} เราสามารถวนซ้ำและแสดงค่าใน slice โดยใช้ for range ได้ดังนี้ for _, m := range members { fmt.Println(m) } […]

Continue reading →

for loop

เรื่องการทำงานวนซ้ำสำหรับภาษา Go นั้นมี keyword หลักตัวเดียวนั้นคือ for ที่ทำหน้าที่วนซ้ำ ถ้าใครเคยใช้ภาษาในลักษณะ C มาก่อนน่าจะเข้าใจ รูปแบบการใช้งานเช่น จะเห็นว่าคล้ายกับ C นั่นล่ะ แต่ไม่ต้องมีวงเล็บเปิดปิด ต่อมา ถ้าจะใช้งานในลักษณะเดียวกันแบบ while ของ C ทำได้เช่นกันดังนี้ ถ้าเกิดต้องการวนซ้ำแบบไม่ต้องมีเงื่อนไขอะไรตรง for เลยทำได้ดังนี้ นอกจากนั้น ถ้าเป็นการวนซ้ำในข้อมูลแบบ array, slice, หรือ map สามารถใช้ keyword range ช่วยเพื่อกำหนดค่า index หรือ key และ value ที่อยู่ภายในโครงสร้างข้อมูลที่ว่ามา ในแต่ละรอบของ for ได้ ซึ่ง for ก็จะวนจนครบทุกข้อมูลที่อยู่ภายใน เช่น

Continue reading →

len และ cap ของ slice

ข้อมูลแบบ array และ slice นั้นสามารถหาจำนวนที่เก็บอยู่ได้โดยใช้ function ที่ชื่อ len ซึ่งเป็น builtin function ของ Go ตัวอย่างเช่น l := [3]int {1, 2, 3} println( len(l) )  /* ได้ค่า 3 */ ส่วน slice จะต่างกับ array ตรง ค่า len ที่หาได้ เป็นจำนวนค่าที่ slice เก็บอยู่ แต่เนื้อที่หน่วยความจำที่ slice สามารถใช้ได้จริงๆอาจจะมีมากกว่านั้น เพราะ slice ทำหน้าที่ slice แค่บางส่วนออกมา การสร้าง slice โดยกำหนดทั้งจำนวนข้อมูล และ จำนวนหน่วยความจำสามารถทำได้ดังนี้ l := make([]int, 3, […]

Continue reading →

ข้อมูลแบบ slice

จากคราวก่อนที่บอกว่า array นั้นเป็นข้อมูลที่กำหนดขนาดชัดเจน array ที่มีขนาดต่างกัน ถือว่าเป็นข้อมูลคนละประเภทกันเลย เช่น var a [5]int var b [10]int ถือว่า a และ b เป็นข้อมูลคนละแบบ a เป็น array ของ int ขนาด 5 ตัว และ b เป็น array ของ int ขนาด 10 ตัว ทีนี้ ถ้าเราต้องการจัดการ array ที่มีขนาดต่างๆกัน เราจะทำอย่างไร สำหรับ Go ได้สร้างข้อมูลอีกประเภทขึ้นมาเลยคือ slice นั่นเอง   การประกาศตัวแปรของ slice การประกาศตัวแปรของ slice ทำได้เกือบเหมือน array ต่างกันตรงไม่ต้องกำหนดขนาดนั่นเอง เช่น var […]

Continue reading →

ข้อมูลแบบ array

จริงๆเรื่องนี้มีในโพสที่แปลหนังสือของพี่พัดแล้วล่ะ แต่ยังไม่ได้ publish แต่มันก็รวมอยู่ในนั้นค่อนข้างเยอะ ผมเลยขอหยิบเอา array ออกมาเป็นอีกโพสแล้วกันเพราะว่าใช้กันบ่อยๆ array เป็นข้อมูลพื้นฐานสำหรับภาษา Golang ที่ทำหน้าที่เก็บข้อมูลเป็นลำดับของข้อมูลประเภทเดียวกันและกำหนดขนาดหรือจำนวนข้อมูลที่อยู่ภายใน array เอาไว้คงที่ตั้งแต่ต้น เข้าถึงได้โดยใช้หมายเลข index   ประเภทข้อมูล array Golang ใช้ [เลขบอกจำนวนสมาชิก] เอาไว้หน้าชื่อประเภทข้อมูล เพื่อบอกว่าประเภทข้อมูลที่เราต้องการจริงๆคือ array ของข้อมูลนั้น ที่มีจำนวนตามที่กำหนดภายใน [] ซึ่งถ้าจำนวนภายใน [] ต่างกัน ถือว่าเป็นข้อมูลคนละแบบกัน เช่น [10]int แทน array ของ int จำนวน 10 ตัว [3]int แทน array ของ int จำนวน 3 ตัว [5]string แทน array ของ string จำนวน 5 […]

Continue reading →

โครงสร้าง package, การ import และ scope

Golang แบ่งกลุ่มของโค้ดออกเป็น package ซึ่งทุกไฟล์โค้ด .go ที่อยู่ภายในระดับ directory เดียวกัน จะต้องเป็น package เดียวกัน ยกเว้น test package ที่ไฟล์ลงท้ายด้วย _test.go โดยทั่วไปแล้ว เราจะตั้งชื่อ package ให้ตรงกับชื่อ directory ที่ package นั้นอยู่ แต่จริงๆแล้วไม่จำเป็นต้องเป็นชื่อเดียวกันเสมอไป บาง package เลือกที่จะให้ชื่อ directory ต่างออกไปเพื่อบอกว่า package นั้นเป็น version อะไร ตัวอย่าง โครงสร้าง directory ของ package เช่น  

Continue reading →