英文:
Golang - How to make single struct works together with multiple structs?
问题
我想让单个结构与多个结构一起工作。
在下面的代码中,第一个查询(rows)应该是单个结构,因为它返回单行数据,而第二个查询(anotherquery)应该是多个结构,因为它返回5行数据。
目前,我所做的是将rows和anotherquery都作为多个结构。
以下是server.go的代码:
package main
import (
	"database/sql"
	"github.com/labstack/echo"
	_ "github.com/lib/pq"
	"html/template"
	"io"
	"log"
	"net/http"
)
type Gallery struct {
	Title, Content string
}
type Idcontainer struct {
	Stitle, Suri string
}
func main() {
	e := echo.New()
	e.Get("/post/:uritext", func(c *echo.Context) error {
		rows, err := db.Query("SELECT title, content FROM gallery WHERE uri=$1", c.Param("uritext"))
		anotherquery, err := db.Query("SELECT title AS stitle, uri AS suri FROM archive WHERE uri!=$1 LIMIT 5", c.Param("uritext"))
		gallery := []Gallery{}
		idcontainer := []Idcontainer{}
		for rows.Next() {
			g := Gallery{}
			err := rows.Scan(&g.Title, &g.Content)
			gallery = append(gallery, g)
		}
		for anotherquery.Next() {
			g := Idcontainer{}
			err := anotherquery.Scan(&g.Stitle, &g.Suri)
			idcontainer = append(idcontainer, g)
		}
		type Model struct {
			Galleries    []Gallery
			Idcontainers []Idcontainer
		}
		return c.Render(http.StatusOK, "onlytestingtpl", Model{
			Galleries:    gallery,
			Idcontainers: idcontainer,
		})
	})
	e.Run(":4444")
}
模板:
{{define "onlytestingtpl"}}
    {{.Title}}<br>
    {{.Content}}
    <h1>ID number:</h1>
    {{range .Idcontainers}}
    <a href='{{.Suri}}'>{{.Stitle}}</a>
    {{end}}
{{end}}
英文:
I want to make single struct works together with multiple structs.
In below codes, first query (rows) should be single struct because it return single row, while the second query (anotherquery) should be multiple struct because it return 5 rows.
Currently, what can I do is I make rows & anotherquery as multiple struct.
Below is server.go:
package main
import (
	"database/sql"
	"github.com/labstack/echo"
	_ "github.com/lib/pq"
	"html/template"
	"io"
	"log"
	"net/http"
)
type Gallery struct {
	Title, Content string
}
type Idcontainer struct {
	Stitle, Suri string
}
func main() {
	e := echo.New()
	e.Get("/post/:uritext", func(c *echo.Context) error {
		rows, err := db.Query("SELECT title, content FROM gallery WHERE uri=$1", c.Param("uritext"))
		anotherquery, err := db.Query("SELECT title AS stitle, uri AS suri FROM archive WHERE uri!=$1 LIMIT 5", c.Param("uritext"))
		gallery := []Gallery{}
		idcontainer := []Idcontainer{}
		for rows.Next() {
			g := Gallery{}
			err := rows.Scan(&g.Title, &g.Content)
			gallery = append(gallery, g)
		}
		for anotherquery.Next() {
			g := Idcontainer{}
			err := anotherquery.Scan(&g.Stitle, &g.Suri)
			idcontainer = append(idcontainer, g)
		}
		type Model struct {
			Galleries    []Gallery
			Idcontainers []Idcontainer
		}
		return c.Render(http.StatusOK, "onlytestingtpl", Model{
			Galleries:    gallery,
			Idcontainers: idcontainer,
		})
	})
	e.Run(":4444")
}
Template:
{{define "onlytestingtpl"}}
    {{.Title}}<br>
    {{.Content}}
    <h1>ID number:</h1>
    {{range .Idcontainers}}
    <a href='{{.Suri}}'>{{.Stitle}}</a>
    {{end}}
{{end}}
答案1
得分: 1
我认为使代码正常工作的最小更改如下所示。
将这段代码更改为:
    type Model struct {
        Gallery    Gallery // 你说只有一个画廊对吧?
        Idcontainers []Idcontainer
    }
    return c.Render(http.StatusOK, "onlytestingtpl", Model{
        Gallery:    gallery[0],
        Idcontainers: idcontainer,
    })
然后将模板更改为:
{{define "onlytestingtpl"}}
    {{.Gallery.Title}}<br>
    {{.Gallery.Content}}
    <h1>ID number:</h1>
    {{range .Idcontainers}}
    <a href='{{.Suri}}'>{{.Stitle}}</a>
    {{end}}
{{end}}
我在这里尝试了一个简单的示例:http://play.golang.org/p/uedcjXalEH
虽然你没有要求对整个代码进行反馈,但我冒险添加了一些额外的评论:
- 
考虑使用指针(*)来引用对象,而不是每次都进行复制。
 - 
考虑将初始的
rows更改为以下方式:gallery := Gallery{} if !rows.Next() { return rows.Err() } err := rows.Scan(&gallery.Title, &gallery.Content) // anotherquery 保持不变... return c.Render(http.StatusOK, "onlytestingtpl", Model{ Gallery: gallery, Idcontainers: idcontainer, }) - 
这可能只是示例代码,但在实际生产中,你当然需要更多的错误处理

 
希望对你有所帮助。
英文:
I think the minimal change to your code to make this work would be the following.
Change this:
    type Model struct {
        Galleries    []Gallery
        Idcontainers []Idcontainer
    }
    return c.Render(http.StatusOK, "onlytestingtpl", Model{
        Galleries:    gallery,
        Idcontainers: idcontainer,
    })
To this:
    type Model struct {
        Gallery    Gallery // you said that theres only a single gallery right?
        Idcontainers []Idcontainer
    }
    return c.Render(http.StatusOK, "onlytestingtpl", Model{
        Gallery:    gallery[0],
        Idcontainers: idcontainer,
    })
And then change your template to this:
{{define "onlytestingtpl"}}
    {{.Gallery.Title}}<br>
    {{.Gallery.Content}}
    <h1>ID number:</h1>
    {{range .Idcontainers}}
    <a href='{{.Suri}}'>{{.Stitle}}</a>
    {{end}}
{{end}}
I've tried to mock up a simple example here: http://play.golang.org/p/uedcjXalEH
Though you haven't asked for feedback on the code overall, I'll risk adding a few additional comments:
- 
Consider using * (pointers) to objects rather than making copies each time.
 - 
Consider changing your initial
rowsto work something like this:gallery := Gallery{} if !rows.Next() { return rows.Err() } err := rows.Scan(&gallery.Title, &gallery.Content) // anotherquery remains the same ... return c.Render(http.StatusOK, "onlytestingtpl", Model{ Gallery: gallery, Idcontainers: idcontainer, }) - 
This is probably just example code but in production you'll need more error handling of course

 
Hope this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论