Multiple return values

Go สามารถเขียน Function ให้สามารถ return หลายค่าออกมาได้ ซึ่งถ้าดูจาก standard package จะเห็นว่าส่วนใหญ่ใช้ไปกับการส่งค่า error กลับออกมาเป็นค่าที่สองของ Function ซะเยอะ มีบ้างบาง Function ที่ส่งกลับ 3 ค่า แต่น้อยมาก ตัวอย่างเช่น Function os.Open ใน package os ที่เอาไว้เปิดไฟล์ถูกประกาศไว้ดังนี้ func Open(name string) (file *File, err error) เวลาใช้งาน ถ้าเราต้องการรับค่าจาก Function Open มาเก็บไว้ ด้านซ้ายของเครื่องหมาย = หรือ := ก็ต้องกำหนดตัวแปรสองตัวตามลำดับไว้สำหรับเก็บ file และ err เช่น f, err := os.Open(“test.txt”) ทีนี้เราลองสร้างของเราเองสัก Function เช่นเราต้องการสร้าง […]

Continue reading →

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 →

ทำ 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 →

อ่านข้อมูลจาก json ไฟล์

หลายครั้งที่เราต้องทำงานกับข้อมูลที่ถูก export ออกมาจาก database และข้อมูลเหล่านั้นถูกจัดออกมาให้อยู่ในรูปแบบ json ซึ่งสำหรับ go แล้วเราสามารถทำงานในลักษณะนี้ได้อย่างสะดวกรวดเร็วยกตัวอย่างเช่นเรามีข้อมูลที่เป็น json format ดังนี้ จากนั้นสิ่งที่เราต้องทำคือการเขียนโค้ด (แน่นอนอยู่แล้วถ้าไม่เขียนโค้ดมันจะทำงานได้อย่างไร) กระบวนการทำงานจะประกอบไปด้วยสองขั้นตอนคือ การเปิดไฟล์ขึ้นมาอ่านจากตำแหน่งที่เรากำหนดซึ่งเราจะใช้ฟังก์ชั่นจาก package ชื่อ “io/ioutil” การอ่าน content จาก json นั้นเราจำเป็นต้องใช้ของจาก package อื่นนั่นคือ “encoding/json”

Continue reading →

การทดสอบด้วยตัวอย่างใน Go

การทดสอบด้วยการใช้ตัวอย่างเป็นการทดสอบโดยการ execute function ที่จะใช้ทดสอบและนำ Standard Output มาเปรียบเทียบกับผลลัพธ์ที่ได้ โดยการที่จะรันการทดสอบแบบนี้ต้องจะมี convention คือ ชื่อฟังก์ชั่นต้องขึ้นต้นด้วย Example เช่น “func ExampleTime_Format()” ต้องมี comment code ขึ้นต้นด้วย Output: (หรือ output:) หากไม่มี go จะคอมไพล์แต่ไม่เรียกฟังก์ชั่นให้ การตั้งชื่อของ Example ฟังก์ชั่นเราจะลงท้ายด้วยชื่อของฟังก์ชั่นหรือ type หรือ type_method ที่ใช้สำหรับทดสอบ  เช่นExamplePrintln // เป็นการทดสอบด้วยตัวอย่างของฟังก์ชั่น Println ExampleTime // เป็นการทดสอบด้วยตัวอย่างของ type Time ExampleTime_Format // เป็นการทดสอบด้วยตัวอย่าง method Format ของ type Time ยกตัวอย่างเช่น การรันการทดสอบด้วยตัวอย่างทำได้โดยใช้คำสั่ง go test ผลลัพธ์ที่ได้เมื่อใส่ option […]

Continue reading →