Golang-如何使单个结构与多个结构一起工作?

Golang-如何使单个结构与多个结构一起工作?

问题描述:

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}}

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 rows to 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.