go 的结构体没有构造函数,可以通过工厂模式来创建实例并初始化数据
由一个需求引出工厂模式
-
我们都知道,定义结构体的时候,如果结构体的名字大写,是可以被其他包访问的;如果结构体的名字小写,则只能在当前包内访问。
-
同样的,结构体内部的字段名如果是大写开头的,也可以被其他包访问;如果是小写开头的,则只能在当前包内访问。
-
比如以下的 User 结构体,Name 和 Age 字段都是大写开头的,因此它们可以被其他包访问和修改:
type User struct {
Name string
Age int
}
-
然而实际情况可能是这样的,结构体的命名和内部字段都是小写的,这样就无法直接在其他包中创建实例并访问字段了
-
比如以下的 user 结构体,age 字段都是小写开头的,因此它们只能在当前包内访问和修改:
type user struct {
Name string
age int
}
-
那如果我们非要使用这个结构体或者结构体内部字段呢?这时候就可以通过工厂模式来创建实例并初始化数据了
通过工厂模式来创建实例并初始化数据
main 包中需要访问 user 包中的 user 结构体,并且需要访问 user 结构体中的 age 字段。
使用工厂模式来实现这个需求
-
1、在 user 包中定义 user 结构体
-
2、在 user 包中,使用工厂模式 NewUser 来创建 user 结构体的实例
-
3、在 user 包中,提供公共方法 GetAge 和 SetAge 来访问和修改 age 字段
package user
type user struct {
Name string
age int
}
func NewUser(name string, age int) *user {
return &user{
Name: name,
age: age,
}
}
// 通过公共方法访问 age 字段
func (u *user) GetAge() int {
return u.age
}
// 通过公共函数访问 age 字段
func GetUserAge(u *user) int {
return u.age
}
// 通过公共方法修改 age 字段
func (u *user) SetAge(age int) {
u.age = age
}
// 通过公共函数修改 age 字段
func SetUserAge(u *user, age int) {
u.age = age
}
-
4、在 main 包中调用工厂模式来创建 user 结构体的实例
-
5、在 main 包中调用公共方法和公共函数来访问和修改 age 字段
package main
import (
"fmt"
"user"
)
func main() {
u := user.NewUser("Alice", 30)
fmt.Println("Name:", u.Name) // 可以直接访问 Name 字段
fmt.Println("Age:", u.GetAge()) // 通过公共方法访问 age 字段
fmt.Println("Age:", user.GetUserAge(u)) // 通过公共函数访问 age字段
u.SetAge(31) // 通过公共方法修改 age 字段
fmt.Println("Age:", u.GetAge()) // 通过公共方法访问 age 字段
user.SetUserAge(u, 32) // 通过公共函数修改 age 字段
fmt.Println("Age:", user.GetUserAge(u)) // 通过公共函数访问 age字段
fmt.Println("Name:", u.Name) // 输出 Alice (可以直接访问 Name 字段,因为 Name 字段是大写开头的,可以被其他包访问和修改)
u.Name = "Bob" // 可以直接修改 Name 字段
fmt.Println("Name:", u.Name) // 输出 Bob ( 可以直接访问 Name 字段)
}