// config/config.go
package config
import (
"github.com/spf13/viper"
)
type Config struct {
Database DatabaseConfig `mapstructure:"database"`
Server ServerConfig `mapstructure:"server"`
Redis RedisConfig `mapstructure:"redis"`
Jwt JwtConfig `mapstructure:"jwt"`
Smtp SmtpConfig `mapstructure:"smtp"`
}
func New() (config *Config) {
viper.AddConfigPath(".")
viper.SetConfigName("config")
if err := viper.ReadInConfig(); err != nil {
panic(err)
}
if err := viper.Unmarshal(&config); err != nil {
panic(err)
}
return
}
// db/connection.go
package db
import (
"fmt"
"my.project/config"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func New(config config.DatabaseConfig) *gorm.DB {
dsn := fmt.Sprintf(
"%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
config.Username, config.Password, config.Host, config.Port, config.Database,
)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Println("Failed to connect to database")
panic(err)
}
RunMigrations(db)
return db
}
// main.go
package main
import (
"fmt"
"my.project/config"
)
func main() {
config := config.New()
fmt.Println(config.Database)
db := db.New(config.Database)
if db == nil {
panic("Failed to connect to database")
}
}
在上面的代码段中,config
是指向Config类型变量的指针(显然来自config.New()
的返回类型(,但config.Database
似乎是一个值(而不是引用(
我认为config.Database
也会是一个引用,但事实并非如此(我试图打印出来,config
肯定是一个参考,config.Database
是一个值(
有人能帮我理解为什么吗?提前谢谢!
事实证明,这源于一个语言设计决策。事实上,如果您使用(*config).Database
,它是绝对有效的。然而,Go的制作者认为这种符号很麻烦,因此该语言允许我们编写config.Database
,而没有明确的取消引用。这些指向结构的指针甚至有自己的名称struct pointers
,并且它们被自动取消引用。以下是对";"自动延迟":什么时候出发;s指针自身取消引用