สวัสดีครับ ในบทความนี้ก็เป็น EP.3 แล้วนะครับ โดยเนื้อหาจะเป็นเรื่องเกี่ยวกับ Go packages ว่าคืออะไร ใช้ทําอะไร และมีประโยชน์อย่างไร
สําหรับท่านใดที่ยังไม่ได้อ่าน EP.2 ท่านสามารถกลับไปอ่านก่อนได้นะครับที่นี่ Go EP.2 ทําความรู้จักกับ Go module
Go packages คืออะไร
Go packages คือ การแบ่ง Sorce code ของเราออกแป็นส่วนๆได้ ยกตัวอย่างเช่น โดยปกติแล้วโปรแกรมที่เราเขียนขึ้นมาสักตัวหนึ่ง แน่นอนว่าภายในจะประกอบไปด้วยส่วนต่างๆมากมาย ดังนั้นเพื่อความเป็นระเบียบ ดูแลได้ง่าย และที่สําคัญสามารถ Reuse sorce code ได้ เราจําเป็นจะต้องแยก Sorce code ออกเป็นส่วนๆ โดยใช้ความสามารถของ Go packages นั้นละครับ และไม่เพียงแค่แบ่ง Sorce code ภายใน Project เท่านั้น Go packages ยังสามารถนําไปใช้ประโยชน์เมื่อเราต้องการจะ Public sorce code ของเราให้คนอื่นๆได้ใช้อีกด้วย เหมือนกับบทความ Go EP.2 ทําความรู้จักกับ Go module ที่เราใช้คําสั่ง go get … เพื่อนํา Sorce code หรือ Dependency ของคนอื่นๆมาใช้ใน Project ของเรา
การใช้งาน Go packages
การใช้งาน Go package ก็ไม่มีอะไรมาครับ เราสามารถใช้ Keyword “package” ใส่ไว้ในตอนต้นของไฟล์แค่นั้นครับ ตามตัวอย่างนี้ครับ
package main
import "fmt"
func main() {
fmt.Println("Hello Go")
}
จากตัวอย่างด้านบนหมายถึง package main ครับ
สร้าง Package แรก
มาลองสร้าง Package แรกกันครับ
ตัวอย่างเราจะสร้าง Package hello และเราจะ Import เข้าไปใช้ใน package main ครับ
เริ่มต้นโดยการสร้างไฟล์ไว้ใน folder ประมาณนี้
my-project
├─ go.mod
├─ go.sum
├─ hello
| └─ hello.go
└─ main.go
แล้วเพิ่ม Sorce code เข้าไปใน hello.go ตามนี้
package hello
import "fmt"
func SayHi() {
fmt.Println("Hello world")
}
และนําไป Import ใน main.go ประมาณนี้ครับ
package main
import (
"github.com/mrthiti/go-module-example/hello"
)
func main() {
hello.SayHi()
}
เมื่อรันแล้วจะได้ผลลัพธ์ “Hello world” ครับ
จะเห็นเวลาเวลา Import Package ที่อยู่ภายใน module เดียวกัน จะใช้ชื่อ module แล้วตามด้วย ชื่อ Package
- github.com/mrthiti/go-module-example <- ชื่อ module ของ Project เรา
- /hello <- ชื่อ package ที่เราต้องการ Import
ส่วนรายละเอียด Convention ต่างๆ จะอธิบายในหัวข้อถัดไปนะครับ
Go package convention
Package main
จะเห็นว่าจากตัวอย่างที่ผ่านมาจะมีการใส่ Package main ซึ่งในภาษา Go เมื่อเรากําหนดชื่อของ Package เป็น “main” หมายความว่า จะเป็นการบอกตัว Compiler ของภาษา Go ให้รู้ว่า ไฟล์นั้นจะเป็นไฟล์ที่ถูก Execute หรือ เป็นไฟล์ที่ถูก Run
package main // <-- กําหนด Package เป็นชื่อ main
import "fmt"
func main() {
fmt.Println("Hello Go")
}
Exported vs Unexported names
ในภาษา Go นั้นไม่มี Class นะครับ ดังนั้นเราจะไม่สามารถเขียน OOP แบบพวกภาษาอื่นๆเช่น Java ได้ แต่ Go จะมีสิ่งที่เรียกว่า Exported vs Unexported names หมายถึง เราสามารถกําหนดได้ว่า ตัวแปร, Function หรือ Type สามารถเรียกใช้จาก Package ภายนอกได้หรือไม่ ด้วยวิธีการดังนี้
- กำหนดตัวอักษรแรกเป็นตัวพิมพ์ใหญ่ - สามารถเรียกใช้จาก Package อื่นๆได้ หรือในภาษาอื่นๆก็จะเรียกว่า Public ครับ
- กำหนดตัวอักษรแรกเป็นตัวพิมพ์เล็ก - จะไม่สามารถเรียกใช้จาก Package อื่นๆได้ หรือในภาษาอื่นๆก็จะเรียกว่า Private ครับ
มาดูตัวอย่างกันครับ
package hello
import "fmt"
func SayHi() { // <- สามารถถูกเรียกใช้จาก Package อื่นๆได้
fmt.Println(getHelloText())
}
func getHelloText() string { // <- ไม่สามารถถูกเรียกใช้จาก Package อื่นๆได้
return "Hello world"
}
Function SayHi() จะสามารถถูกเรียกใช้จาก Package อื่นๆได้ แต่ Function getHelloText() ไม่สามารถถูกเรียกใช้จาก Package อื่นๆได้ จะเรียกใช้ได้เฉพาะภายใน Package เดียวกันเท่านั้น
*ภายใน Folder เดียวกันสามารถมีได้แค่ Package เดียวเท่านั้นนะครับ
/internal Directory
ในภาษา Go Directory /internal เป็น Directory พิเศษ หมายถึง Package ที่อยู่ภายใต้ Directory /internal จะไม่สามารถ Import จาก Package ที่อยู่ลําดับชั้นที่เหนือขึ้นไปเกิน 1 ชั้น ได้ เพื่อให้เข้าใจมากขึ้น ลองดูตามตัวอย่างนี้ครับ
my-project
├─ go.mod
├─ go.sum
├─ aaa
| ├─ internal
| | └─ bbb
| | └─ bbb.go
| └─ aaa.go
└─ main.go
จากโครงสร้าง Project ด้านบนสามารถอธิบายได้ดังนี้ครับ
- Package main สามารถ เรียกใช้ Package aaa ได้ แต่จะไม่สามารถเรียกใช้ Package bbb ได้
- Package aaa สามารถ เรียกใช้ Package bbb ได้
Directory internal/ จะช่วยให้เรา สามารถจัดการการ access หรือ visibility ใน Project ของเราได้ครับ
สําหรับเนื้อหาเกี่ยวกับ Go package ก็จะประมาณนี้นะครับ
สําหรับ EP. ต่อไปจะเป็นเรื่อง Go EP.4 Syntax ของภาษา Go เข้าไปอ่านต่อได้เลยครับ
ขอให้สนุกกับการเขียนโปรแกรมนะครับ ขอบคุณครับ 😀