我刚刚开始使用golang,我试图从Postgres users表中读取几行,并将结果存储为一个User对行进行建模的结构数组.
type User struct {
Id int
Title string
}
func Find_users(db *sql.DB) {
// Query the DB
rows, err := db.Query(`SELECT u.id, u.title FROM users u;`)
if err != nil { log.Fatal(err) }
// Initialize array slice of all users. What size do I use here?
// I don't know the number of results beforehand
var users = make([]User, ????)
// Loop through each result record, creating a User struct for each row
defer rows.Close()
for i := 0; rows.Next(); i++ {
err := rows.Scan(&id, &title)
if err != nil { log.Fatal(err) }
log.Println(id, title)
users[i] = User{Id: id, Title: title}
}
// .... do stuff
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我的问题是我想事先初始化一个数组或切片以存储所有数据库记录,但我不知道会提前记录多少条记录.
我正在权衡几种不同的方法,并希望找出以下哪些在golang社区中使用最多 -
事先创建一个非常大的数组(例如10,000个元素).似乎很浪费
事先明确计算行数.这可能有效,但我需要运行2个查询 - 一个用于计数,一个用于获取结果.如果我的查询很复杂(这里没有显示),那就是在2个地方复制那个逻辑.或者,我可以运行相同的查询两次,但首先循环它并计算行.这一切都会奏效,但看起来似乎不洁净.
我见过扩展切片的例子.我不太了解切片,看看它如何适应这里.此外,如果我不断扩大10倍的切片,它肯定是浪费.
谢谢!
jos*_*hlf 11
Go具有内置append功能,正是出于此目的.它需要一个切片和一个或多个元素,并将这些元素附加到切片,返回新切片.此外,slice(nil)的零值是一个长度为零的切片,因此如果您附加到零切片,它将起作用.因此,您可以这样做:
type User struct {
Id int
Title string
}
func Find_users(db *sql.DB) {
// Query the DB
rows, err := db.Query(`SELECT u.id, u.title FROM users u;`)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
var users []User
for rows.Next() {
err := rows.Scan(&id, &title)
if err != nil {
log.Fatal(err)
}
log.Println(id, title)
users = append(users, User{Id: id, Title: title})
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
小智 7
用户附加到切片:
type DeviceInfo struct {
DeviceName string
DeviceID string
DeviceUsername string
Token string
}
func QueryMultiple(db *sql.DB){
var device DeviceInfo
sqlStatement := `SELECT "deviceName", "deviceID", "deviceUsername",
token FROM devices LIMIT 10`
rows, err := db.Query(sqlStatement)
if err != nil {
panic(err)
}
defer rows.Close()
var deviceSlice []DeviceInfo
for rows.Next(){
rows.Scan(&device.DeviceID, &device.DeviceUsername, &device.Token,
&device.DeviceName)
deviceSlice = append(deviceSlice, device)
}
fmt.Println(deviceSlice)
}
Run Code Online (Sandbox Code Playgroud)