项目结构如下:
decoder ├── config.json └── decoder.go
config.json 文件内容
{ "ServerInfo": { "Host": "127.0.0.1:8888" }, "RedisInfo": { "Host": "127.0.0.1:6379", "MaxIdle": 16, "MaxActive": 0, "IdleTimeout": 300 } }
decoder.go 文件内容
package main import ( "encoding/json" "fmt" "os" "time" ) type Config struct{} type ConfigurationType struct { ServerInfo ServerInfoType RedisInfo RedisInfoType } type ServerInfoType struct { Host string } type RedisInfoType struct { Host string MaxIdle int MaxActive int IdleTimeout time.Duration } var COnfiguration= ConfigurationType{} func (this Config) InitConfig() { file, _ := os.Open("config.json") defer file.Close() decoder := json.NewDecoder(file) COnfiguration= ConfigurationType{} err := decoder.Decode(&Configuration) if err != nil { fmt.Println("Error: ", err) } fmt.Printf("Configuration: %v\n", Configuration) } func main() { conf := Config{} conf.InitConfig() }
这种情况下我运行:go run decoder.go
, 输出结果如下:
Configuration: {{127.0.0.1:8888} {127.0.0.1:6379 16 0 300ns}}
但是我把这个 main 包改为 decoder 包,项目结构调整如下
. ├── decoder │ ├── config.json │ └── decoder.go └── main.go
config.json 文件内容
{ "ServerInfo": { "Host": "127.0.0.1:8888" }, "RedisInfo": { "Host": "127.0.0.1:6379", "MaxIdle": 16, "MaxActive": 0, "IdleTimeout": 300 } }
decoder.go 文件内容
package decoder import ( "encoding/json" "fmt" "os" "time" ) type Config struct{} type ConfigurationType struct { ServerInfo ServerInfoType RedisInfo RedisInfoType } type ServerInfoType struct { Host string } type RedisInfoType struct { Host string MaxIdle int MaxActive int IdleTimeout time.Duration } var COnfiguration= ConfigurationType{} func (this Config) InitConfig() { file, _ := os.Open("config.json") defer file.Close() decoder := json.NewDecoder(file) COnfiguration= ConfigurationType{} err := decoder.Decode(&Configuration) if err != nil { fmt.Println("Error: ", err) } fmt.Printf("Configuration: %v\n", Configuration) }
main.go 文件内容
package main import "initTest/decoder" func main() { t := decoder.Config{} t.InitConfig() }
测试运行 go run main.go
报错如下:
Error: invalid argument Configuration: {{} { 0 0 0s}}
请问是否有人知道是什么原因?
![]() | 1 freestyle 2019-06-19 08:44:33 +08:00 via iPhone ![]() 这不是包导入的问题, file, _ := os.Open("config.json") 你用的是相对路径,会从运行的工作目录(执行 go run main.go 的目录)下查找,实际上代码运行到这一步就出错了,找不到文件. 配置文件路径应该用函数参数去传递,而不是写死在函数里面. 要正确处理 error. |
![]() | 2 wewin OP @freestyle 哎哟,我去,被闪了腰。现在用的语言文件找不到直接是跑出了异常,go 语言这种直接返回 err 的还真的不太习惯。 将 decoder.go InitConfig 方法改了: ``` ... func (this Config) InitConfig() { file, err := os.Open("config.json") defer file.Close() if err != nil { fmt.Printf("Open file error: %v\n", err) } decoder := json.NewDecoder(file) COnfiguration= ConfigurationType{} err = decoder.Decode(&Configuration) if err != nil { fmt.Println("Error: ", err) } fmt.Printf("Configuration: %v\n", Configuration) } ``` 将读文件的 err 信息打印出来了。 感谢! |
3 donething 2019-06-19 13:10:14 +08:00 via Android 再挑个次要问题,defer file.Close()应该放在 if err != nil 之后 |
5 donething 2019-06-19 15:10:57 +08:00 via Android @wewin 如果打开文件若有错误发生,就不需要调用 file.Close(),所以写在 if err!=nil 语句后面。 |
8 donething 2019-06-19 19:07:23 +08:00 via Android if err != nil { return err } defer file.close() |
9 labulaka 2019-06-20 11:07:26 +08:00 via Android 任何时候别忽略 err |
10 anonymous256 2019-06-20 23:20:21 +08:00 via Android 我也很烦 golang 每次都要判断 err,所以一般就写个函数 func checkErr(err error){ if err != nil{ // do something } } 这样每次都只直接调用这个 checkErr,而不是判断它是不是等于 nil 了,比较偷懒的写法 |