avatar
thiti.dev
วงแหวนเว็บ
Search
Tags
My CV
Contact
Support me
Go EP.3 Go packages คืออะไร
28 Aug 2021

สวัสดีครับ ในบทความนี้ก็เป็น 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/thiti-y/go-module-example/hello"
)

func main() {
    hello.SayHi()
}

เมื่อรันแล้วจะได้ผลลัพธ์ "Hello world" ครับ

จะเห็นเวลาเวลา Import Package ที่อยู่ภายใน module เดียวกัน จะใช้ชื่อ module แล้วตามด้วย ชื่อ Package

  • github.com/thiti-y/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 เข้าไปอ่านต่อได้เลยครับ

ขอให้สนุกกับการเขียนโปรแกรมนะครับ ขอบคุณครับ 😀

thiti.dev © 2021 Thiti Yamsung