我开始尝试使用Go,到目前为止,这是一次爆炸。我决定制作一个小应用程序,帮助朋友在他的(小)公司中组织信息业务相关信息,我想我会用Go来实现它。
我没有(确切地)遇到问题,这更像是一个问题,我应该何时考虑使用反射?例如,我有3种相关类型:Company
,Project
和Staff
。它们都有几个共同的字段(例如id
,name
),所以你可以想象,从数据库中加载它们的函数(我正在使用MySQL
)都非常类似。
查看LoadCompany()
,LoadStaff()
和LoadProject()
:
// Loads the company from the database with the given id.
func LoadCompany(id int) (Company, error) {
db := tools.OpenDB()
defer db.Close()
stmt, err := db.Prepare("SELECT * FROM companies WHERE id = ?")
if err != nil {
log.Panic(err)
}
var c Company
err = stmt.QueryRow(id).Scan(&c.id, &c.FullName, &c.Name, &c.History, &c.Overview, &c.Est, &c.Phone, &c.Website, &c.Email)
if err != nil {
return Company{}, err
}
return c, nil
}
// Loads the staff from the database with the given id.
func LoadStaff(id int) (Staff, error) {
db := tools.OpenDB()
defer db.Close()
stmt, err := db.Prepare("SELECT * FROM staff WHERE id = ?")
if err != nil {
log.Panic(err)
}
var s Staff
err = stmt.QueryRow(id).Scan(&s.id, &s.FullName, &s.Name, &s.Email, &s.Joined, &s.Left, &s.History, &s.Phone, &s.Position)
if err != nil {
return Staff{}, err
}
return s, nil
}
// Loads the project from the database with the given id.
func LoadProject(id int) (Project, error) {
db := tools.OpenDB()
defer db.Close()
stmt, err := db.Prepare("SELECT * FROM projects WHERE id = ?")
if err != nil {
log.Panic(err)
}
var p Project
err = stmt.QueryRow(id).Scan(&p.id, &p.Title, &p.Overview, &p.Value, &p.Started, &p.Finished, &p.Client, &p.Architect, &p.Status)
if err != nil {
return Project{}, err
}
return p, nil
}
当我写LoadCompany()
时,我对自己感觉非常好( ahem 作为初学者/中级程序员),因为它看起来很简洁。但是当我写LoadStaff()
和LoadProject()
时,我所做的只是复制和调整。我确信有更好的方法可以做到这一点,但在阅读Pike's post on it之后,我厌倦了跳入反思:
<反思是一种强有力的工具,除非有必要,否则应谨慎使用并避免使用。
所以我的问题是,我应该使用反射,如果是这样,你能给我一些关于最佳技术的指针吗?这只是冰山一角,因为我觉得与这些类型相关的其他功能和方法都是同样重复的(并且不要让我开始测试!)。
谢谢!
答案 0 :(得分:2)
类似的东西:
func LoadObject(sql string, id int, dest ...interface{}) error {
db := tools.OpenDB()
defer db.Close()
stmt, err := db.Prepare(sql)
if err != nil {
log.Panic(err)
}
defer stmt.Close()
return stmt.QueryRow(id).Scan(dest)
}
// Loads the company from the database with the given id.
func LoadCompany(id int) (c Company, err error) {
err = LoadObject("SELECT * FROM companies WHERE id = ?", &c.id,
&c.FullName, &c.Name, &c.History, &c.Overview, &c.Est, &c.Phone, &c.Website, &c.Email)
return
}
请注意,我还没有编译这段代码,但希望它能够给你一个好主意。
一些建议:
sql.DB
实例一次select full_name, history, .... from companies ....
)