英文:
Controlling a Pointer in Go
问题
我正在尝试遍历rows
,在查询数据库后,但我在第二次遍历中找到females
时遇到了问题。
我认为这是因为在遍历rows
并打印出男性后,指针停留在末尾,无法返回。
如何将指针重新放置在开头?还是我需要进行另一个查询?
英文:
I am trying to iterate through rows
after it does a query to a database but I'm having trouble iterating through it a second time to find the females
.
I believe this is because of the fact that after it iterates through rows
printing out the men, the pointer is left at the end and can't go back.
rows2, rowErr :=db.Query("SELECT GIVENNAME,gender, count(givenname) as Frequency from people group by givenname order by givenname asc")
for rows2.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "male" {
fmt.Println(givenName, gender, frequency)
}
}
fmt.Println("")
for rows2.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "female" {
fmt.Println(givenName, gender, frequency)
}
}
How can I put the pointer at the beginning again? Or will I have to do another query?
答案1
得分: 2
你不能“回滚”指针到先前的值,因此你必须使用另一个(临时)变量来进行迭代。
rows2, rowErr := db.Query("SELECT GIVENNAME, gender, count(givenname) as Frequency from people group by givenname order by givenname asc")
var list1, list2 MyPeopleStruct
temp := rows2
for temp.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "male" {
fmt.Println(givenName, gender, frequency)
}
}
fmt.Println("")
temp = rows2 // 重新初始化为实际需要的值
for temp.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "female" {
fmt.Println(givenName, gender, frequency)
}
}
无论如何,为什么你需要使用两个不同的for loop
呢?
你不能只使用一个完成所有操作吗?像这样:
type MyPeopleStruct struct{
Gender string
Name string
Frequency int
}
rows2, rowErr := db.Query("SELECT GIVENNAME, gender, count(givenname) as Frequency from people group by givenname order by givenname asc")
var listM, listF []MyPeopleStruct
temp := rows2
for temp.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "male" {
fmt.Println(givenName, gender, frequency)
listM = append(listM, MyPeopleStruct{gender,givenName,frequency})
}
if gender == "female" {
fmt.Println(givenName, gender, frequency)
listF = append(listF, MyPeopleStruct{gender,givenName,frequency})
}
}
// 使用 listM 和 listF
英文:
You can't 'rollback' a pointer to a previous value, hence you have to use another (temporary) var which you use to iterate.
rows2, rowErr := db.Query("SELECT GIVENNAME, gender, count(givenname) as Frequency from people group by givenname order by givenname asc")
var list1, list2 MyPeopleStruct
temp := rows2
for temp.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "male" {
fmt.Println(givenName, gender, frequency)
}
}
fmt.Println("")
temp = rows2 // reinitialise it to the actual value you need
for temp.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "female" {
fmt.Println(givenName, gender, frequency)
}
}
<hr>
Anyway, why do you even need to make two different for loop
s?
Can't you do everything using only one? like:
type MyPeopleStruct struct{
Gender string
Name string
Frequency int
}
rows2, rowErr := db.Query("SELECT GIVENNAME, gender, count(givenname) as Frequency from people group by givenname order by givenname asc")
var listM, listF []MyPeopleStruct
temp := rows2
for temp.Next() {
nextErr := rows2.Scan(&givenName,&gender, &frequency)
if nextErr != nil{
log.Fatal(nextErr.Error())
}
if gender == "male" {
fmt.Println(givenName, gender, frequency)
listM = append(listM, MyPeopleStruct{gender,givenName,frequency})
}
if gender == "female" {
fmt.Println(givenName, gender, frequency)
listF = append(listF, MyPeopleStruct{gender,givenName,frequency})
}
}
// Use listM and listF
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论