Skip to main content

การจัดการ Go package

Go package คืออะไร ?

Go package คือ วิธีการจัดการและการ reuse code ใน go โดย

  • ประกาศผ่าน keyword package ที่ตำแหน่งบนสุดของไฟล์
  • ถ้า package คือ main (ไฟล์หลักของ go) = ต้องมี main function เพื่อเป็นจุดเริ่มต้นของ function
  • ไฟล์ go อื่นๆ สามารถ import ผ่าน package ที่ประกาศได้

ประโยชน์ของการใช้ Go Package

  • ทำให้ code ดูเป็นระเบียบ และสามารถ reuse code ได้ง่าย
  • สามารถสร้างเป็น package เพื่อให้คนอื่นสามารถใช้ source code เราได้ (ผ่านคำสั่ง go get ที่เราพึ่งทำไปเมื่อกี้ )

ก่อนไป Go package มารู้จักกับ function ก่อน

Function คือ concept ของ programming ในการรวมชุดคำสั่งเอาไว้เป็นคำสั่งใหม่คำสั่งเดียว เพื่อให้สามารถ reuse การใช้งานได้

เช่น สมมุติว่า เราต้องการเก็บชุดคำสั่งที่แสดงคำว่า "Hello World" เอาไว้ โดยเราสามารถเรียกใช้คำสั่งนี้ในอนาคตได้

  • เราจึงทำการสร้าง function โดยทำการห่อคำสั่งของ "Hello World" เอาไว้ (สมมุติตั้งชื่อว่า sayHello)
  • ใน function main() เราก็จะสามารถเรียกใช้คำสั่ง sayHello() เพื่อเรียกใช้คำสั่งการ print แสดงผลออกมาได้
package main

import (
"fmt"
)

func sayHello() {
fmt.Println("Hello World")
}

func main() {
sayHello()
sayHello()
sayHello()
}

ก็จะได้ผลลัพธ์ sayHello() ออกมาได้ go-package-01

step ต่อไป เดี๋ยวเราจะลองสร้าง function จากไฟล์อื่นและทำการ import เข้ามาบ้าง

ตัวอย่างการประกาศ​ Go package

  • กลับมาที่ Hello World เรามีการประกาศ package main ซึ่งเป็นจุดเริ่มต้นของ package main
package main

import "fmt"

func main() {
fmt.Println("Hello World")
}

เราจะลองสมมุติว่าเราจะย้าย Hello World ไปเป็น Package แทน และตั้งชื่อ package ว่า mikelopster โดยเราจะลองสร้าง structure แบบนี้กัน โดย

  • เราจะสร้าง folder mike
  • ใน folder mike เราจะตั้งชื่อ package name ชื่อ mikelopster
  • จะสร้างตาม structure ด้านล่างนี้
├── go.mod
├── go.sum
├── main.go
└── mike
├── mikelopster.go
└── test.go

โดยทั้ง 2 files นั้นเราจะทำการสร้าง function สำหรับการแสดงข้อความบน console ออกมา

ที่ mikelopster.go

package mikelopster

import "fmt"

func SayMikelopster() {
fmt.Println("Hello mikelopster")
}

ที่ test.go

package mikelopster

import "fmt"

func SayTest() {
fmt.Println("Hello Test")
}

จากนั้นที่ main.go ทำการเรียกใช้ 2 functions นี้โดย

  • import folder package เข้ามา
  • เรียกใช้คำสั่งผ่านชื่อ package ตามด้วย ชื่อ function packageName.functionName() ex. mikelopster.SayHello()
package main

import (
"github.com/mikelopster/go-example/mike" // เป็นชื่อ package เดียวกับที่ init ตอน Go module
)

func main() {
mikelopster.SayMikelopster()
mikelopster.SayTest()
}

แล้วลอง go run main.go ก็จะได้ผลลัพธ์ออกมา

go-package-02

private function และ public function

ทีนี้เราจะลองมาเปลี่ยนอะไรกันสักเล็กน้อย

  • ที่ mike/test.go เราลองเปลี่ยนชื่อจาก SayTest() เป็น sayTest()
package mikelopster

import "fmt"

func sayTest() {
fmt.Println("Hello Test")
}

เมื่อลองกลับมาดูที่ main.go จะพบว่าเกิด error บางอย่างเกิดขึ้น

go-package-03

  • Error ที่เกิดขึ้น เกิดจากการที่ Go นั้นมองไม่เห็น function sayTest() ที่อยู่ใน mike/test.go

  • เนื่องจาก Convension (ข้อตกลง) ของ Go กำหนดไว้ว่า

    • function ที่ขึ้นต้นด้วยตัวพิมพ์เล็ก = private function (ที่เรียกใช้จากภายใน package เดียวกันได้เท่านั้น)
    • function ที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่ = public function (ที่เรียกใช้จากภายในหรือภายนอกก็ได้)
  • ย้อนกลับไปดูเคสตัวอย่างของ sayHello() ใน main.go จะสังเกตว่าสามารถเรียกใช้งาน function ได้เนื่องจากอยู่ใน package เดียวกัน

กลับกัน หากเรานำ sayTest() ไปเรียกใช้งานจากไฟล์ mike/mikelopster.go

package mikelopster

import "fmt"

func SayMikelopster() {
fmt.Println("Hello mikelopster")
sayTest()
}

แล้วให้ที่ main.go เรียกใช้เพียง SayMikelopster()

package main

import (
"github.com/mikelopster/go-example/mike"
)

func main() {
mikelopster.SayMikelopster()
}

จะสามารถเรียกใช้งานออกมาได้

go-package-04

Note สำหรับเรื่องของ package

  1. go ไม่มี concept class ทุกอย่างจัดการผ่าน function และ package
  2. ใน 1 folder สามารถมีได้เพียง package เดียวเท่านั้น (หากตั้งชื่อ package ต่างกัน ใน folder เดียวกัน = จะเกิด error ออกมา)
  3. go มี folder ชื่อ internal ในการจัดการการมองเห็นได้ เช่น
  • หากเรามี library เพิ่มเติมเป็นแบบนี้ เช่นมี folder internal/lopster ที่เป็น package lopster
├── go.mod
├── go.sum
├── main.go
└── mike
├── internal
│ └── lopster
│ └── lopster.go
├── mikelopster.go
└── test.go
  • main.go จะ
    • สามารถเรียกใช้ package ของ mikelopster ได้ (ใน folder mike)
    • แต่ ไม่สามารถ เรียกใช้ pacakge lopster ที่อยุ่ใน internal ได้ จะเกิดเป็น error (แบบภาพนี้ขึ้นมา)

go-package-05

  • แต่ถ้าเป็นที่ mikelopster.go (ที่อยู่ level เดียวกันกับ internal) จะสามารถเรียกใช้ package lopster ได้ (เนื่องจากเป็น internal ของ package mikelopster)

go-package-06

และนี่คือพื้นฐานเริ่มต้นทั้งหมดของ Go สำหรับการ run พื้นฐานเบื้องต้น

Session ต่อไป เราจะมาลอง Basic programming ของ Go กัน