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

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

โดยทั่วไปแล้ว เราจะตั้งชื่อ package ให้ตรงกับชื่อ directory ที่ package นั้นอยู่ แต่จริงๆแล้วไม่จำเป็นต้องเป็นชื่อเดียวกันเสมอไป บาง package เลือกที่จะให้ชื่อ directory ต่างออกไปเพื่อบอกว่า package นั้นเป็น version อะไร

ตัวอย่าง โครงสร้าง directory ของ package เช่น

Package Directory

 

ตัวอย่างนี้คือ package fizzbuzz ภายในไฟล์ fizzbuzz.go ประกาศ package ไว้ดังนี้

package fizzbuzz

import (
        "strconv"
)

func Fizzbuzz(n int) string {
        if n == 3 { 
                return "Fizz"
        }   
        if n == 5 { 
                return "Buzz"
        }   
        return strconv.Itoa(n)
}
fizzbuzz

ส่วนการ import package ของเราเข้าไปใช้งาน เราจะใช้ keyword import ตามด้วย string ของ directory path ของ package ซึ่งถือว่า path เริ่มต้นคือ src ที่อยู่ภายใต้ GOPATH ตัวอย่างการ import fizzbuzz เข้าไปใช้งาน ภายใน package fizzbuzz_test ดังนี้

ackage fizzbuzz_test

import (
        "fizzbuzz"
        "testing"
)

func TestFizzbuzz(t *testing.T) {
        var fz string = fizzbuzz.Fizzbuzz(1)

        if fz != "1" {
                t.Error("expect 1 but got ", fz)
        }
}

func TestFizzbuzz2(t *testing.T) {
        var fz string = fizzbuzz.Fizzbuzz(2)

        if fz != "2" {
                t.Error("expect 2 but got ", fz) 
        }   
}
fizzbuzz_test

จะเห็นว่า เราสามารถเรียกใช้ function หรือ type ที่อยู่ภายใน package fizzbuzz ได้โดยทำการ import package เข้ามา แล้วเวลาใช้งานก็ใช้ชื่อ package ตามด้วย dot แล้วก็ function หรือ type ที่อยู่ภายใน package

ส่วนเรื่อง scope ของการเข้าถึง function และ type ภายใน package นั้น สำหรับ Golang ไม่มีการใช้ keyword อย่าง private, public หรือ protected แบบภาษาอื่น แต่ใช้การตั้งชื่อของที่อยู่ภายใน package ถ้าขึ้นต้นด้วยตัวอักษรภาษาอังกฤษตัวใหญ่ เช่น Fuzzbuzz จะสามารถเรียกใช้ภายนอก package ได้ แต่ถ้าเป็นแบบอื่น จะเรียกใช้ได้เฉพาะภายใช้ package เท่านั้น

เหตุผลที่ Golang เลือกใช้วิธีนี้เพราะ เวลาเราเห็นตัวแปรภายใน package เราสามารถรู้ได้ทันทีว่า ตัวแปรหรือชื่อนั้นเป็นแบบ public หรือ private โดยไม่ต้องไปดูการประกาศเลย