Go 的可見性由開頭字母大小寫決定

Go 沒有 public / private 關鍵字。識別字開頭是大寫就 exported,小寫就只在自己的 package 內看得到。

package main
 
func Pizza() {}   // exported,別的 package 可以呼叫
func hi()    {}   // unexported,只有這個 package 用得到

規則適用於所有 package 層級的識別字,不只函式:

type Vertex struct {
    X int          // exported 欄位
    y int          // unexported,別的 package 讀不到也寫不到
}
 
const MaxSize = 100   // exported
var cache map[string]int   // unexported

struct 的欄位都適用——這會直接影響 encoding/json:小寫欄位不會被序列化,也無法被反序列化填入,因為 json 套件在另一個 package 裡。這是新手最常撞到的地方。

為什麼這樣設計

可見性寫在名字上,讀 code 時不必翻到宣告處就知道這東西是不是對外的。代價是改可見性等於改名字,所有呼叫端都要跟著改——所以命名時就要想清楚它是不是 API 的一部分。

沒有中間層級(沒有 protected、沒有 friend):要嘛整個 package 外都看得到,要嘛只有 package 內看得到。package 就是 Go 的封裝邊界。

相關:Go 的 struct 是一組具名欄位的集合Go 宣告變數的四種寫法