【问题标题】:Fill a struct which contains slices填充包含切片的结构
【发布时间】:2018-08-19 10:08:56
【问题描述】:

我正在尝试收集 Go 的基础知识。

我正在尝试在 golang 中使用结构的预填充值呈现模板。但没有运气

func ServeIndex(w http.ResponseWriter, r *http.Request) {
    p := &Page{
        Title:   " Go Project CMS",
        Content: "Welcome to our home page",
        Posts: []*Post{
            &Post{
                Title:         "Hello World",
                Content:       "Hello, World Thanks for coming to this site",
                DatePublished: time.Now(),
            },
            &Post{
                Title:         "A Post with comments",
                Content:       "Here is the controversial post",
                DatePublished: time.Now(),
                Comments: []*Comment{
                    &Comment{
                        Author:        "Sathish",
                        Comment:       "Nevermind, I guess",
                        DatePublished: time.Now().Add(-time.Hour / 2),
                    },
                },
            },
        },
    }

    Tmpl.ExecuteTemplate(w, "page", p)
}

这是我的结构定义

import (
    "html/template"
    "time"
)

// Tmpl is exported and can be used by other packages
var Tmpl = template.Must(template.ParseGlob("../templates/*"))

type Page struct {
    Title   string
    Content string
    Posts   *[]Post
}

type Post struct {
    Title         string
    Content       string
    DatePublished time.Time
    Comments      *[]Comment
}

type Comment struct {
    Author        string
    Comment       string
    DatePublished time.Time
}

当我尝试通过 main.go 文件运行此代码时,我收到以下错误

../handler.go:60: cannot use []*Comment literal (type []*Comment) as type *[]Comment in field value
../handler.go:62: cannot use []*Post literal (type []*Post) as type *[]Post in field value

你能帮我理解真正的问题是什么吗?我正在关注视频教程。

编辑:根据 mktopriva 建议更新代码

func ServeIndex(w http.ResponseWriter, r *http.Request) {
    p := &Page{
        Title:   " Go Project CMS",
        Content: "Welcome to our home page",
        Posts: *[]Post{
            &Post{
                Title:         "Hello World",
                Content:       "Hello, World Thanks for coming to this site",
                DatePublished: time.Now(),
            },
            &Post{
                Title:         "A Post with comments",
                Content:       "Here is the controversial post",
                DatePublished: time.Now(),
                Comments: *[]Comment{
                    &Comment{
                        Author:        "Sathish",
                        Comment:       "Nevermind, I guess",
                        DatePublished: time.Now().Add(-time.Hour / 2),
                    },
                },
            },
        },
    }

    Tmpl.ExecuteTemplate(w, "page", p)
}

遇到以下错误

../handler.go:45: cannot use Post literal (type *Post) as type Post in array or slice literal
../handler.go:50: cannot use *Post literal (type *Post) as type Post in array or slice literal
../handler.go:55: cannot use Comment literal (type *Comment) as type Comment in array or slice literal
../handler.go:60: invalid indirect of []Comment literal (type []Comment)
../handler.go:62: invalid indirect of []Post literal (type []Post)

【问题讨论】:

  • 您将字段类型声明为 pointers-to-slices,但您提供的是 slice-of-pointers 类型的值。不要在这里使用指向切片的指针,它们有时很有用但在这里没有用。将Comments *[]Comment 更改为Comments []*Comment 以及其他的。
  • @mkopriva 我现在遇到错误 - ../handler.go:45: cannot use Post literal (type *Post) as type Post in array or slice literal ../handler.go: 50:不能使用 *Post 文字(类型 *Post)作为数组或切片文字中的 Post 类型 ../handler.go:55:不能使用评论文字(类型 *Comment)作为数组或切片文字中的类型评论 ../handler .go:60:[]Comment 文字的间接无效(类型 []Comment)../handler.go:62:[]Post 文字的无效间接(类型 []Post)
  • *[]Post{... 是无效的 Go。如果要初始化指向切片的指针,请使用地址运算符。例如&[]Post.
  • 能否请您在答案@mkopriva 中发布更正的代码,这样我可以投票?

标签: go


【解决方案1】:

@mkopriva 是正确的,但我猜这不是你想要的......

您的结构声明稍有偏差,例如,Page 有a pointer to a slice of Post values,您可能想要a slice of Post pointers,因为这通常是人们使用切片的方式。你的声明只需要在类型旁边加上*,而不是[],然后你的创建代码就可以工作了。

import (
    "html/template"
    "time"
)

// Tmpl is exported and can be used by other packages
var Tmpl = template.Must(template.ParseGlob("../templates/*"))

type Page struct {
    Title   string
    Content string
    Posts   []*Post
}

type Post struct {
    Title         string
    Content       string
    DatePublished time.Time
    Comments      []*Comment
}

type Comment struct {
    Author        string
    Comment       string
    DatePublished time.Time
}

【讨论】:

    【解决方案2】:

    您将某些字段类型声明为 pointers-to-slices,但您向它们提供了 slice-of-pointers 类型的值。

    例如,给定字段Comments *[]Comment,您可以像这样初始化它的值:

    Comments: &[]Comment{},
    

    查看此处了解更多替代方案:https://play.golang.org/p/l9HQEGxE5MP


    同样在切片、数组和映射中,如果元素类型已知,即它不是接口,则可以在元素的初始化中省略类型,而只使用花括号,因此代码如下:

    []*Post{&Post{ ... }, &Post{ ... }}
    

    可以改为:

    []*Post{{ ... }, { ... }}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 2019-11-10
      • 2015-04-08
      • 2019-05-23
      • 1970-01-01
      • 2018-12-09
      • 2021-07-28
      相关资源
      最近更新 更多