檔案結構

  ❯ tree .
  .
  ├── config
  │   └── config.go
  ├── config.yml
  └── main.go

  1 directory, 3 files

理論上會把讀取相關檔案的邏輯寫在config/config.go, 這時候的路徑如果能以呼叫的地方為出發點會比較不容易搞混

main.go

package main

import (
  "log"
)

func main() {
  err := config.LoadConfig("./config.yml")
  if err != nil {
    log.Fatal(err)
  }
}

config/config.go

package config

import (
  "fmt"
  "io/ioutil"
  "path/filepath"
  "runtime"
)

func LoadConfig(path string) error {
  _, file, _, _ := runtime.Caller(1)
  content, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), path))
  if err != nil {
    return err
  }
  fmt.Println(string(content)) // for test here

  // 解構config之類的操作 ...

  return nil
}

即便未來多了其他類似cmd/somecmd/main.go的檔案需要用到config, 也不用擔心呼叫時的資料夾位置, 放心的寫呼叫的檔案本身的相對路徑就對了(σ゚∀゚)σ

這裡有一個小小的demo可以參照