Templates Go模板可以';字段上的t调用方法

Templates Go模板可以';字段上的t调用方法,templates,go,go-templates,Templates,Go,Go Templates,我在net/mail.Address周围有一个包装器,它提供了一些编组逻辑。我试图在模板中使用它,但我不断得到无法计算EmailAddress类型中的字段字符串。模板文档说: 数据的niladic方法的名称,前面有句点, 比如 .方法 结果是调用以点为参数的方法的值 接收器,dot.Method() 及 方法调用可以链接并与字段和键组合 到任何深度: .Field1.Key1.Method1.Field2.Key2.Method2 因此,考虑到这一点,我写了以下内容: 主程序包 进口( “字节”

我在
net/mail.Address
周围有一个包装器,它提供了一些编组逻辑。我试图在模板中使用它,但我不断得到
无法计算EmailAddress类型中的字段字符串。模板文档说:

数据的niladic方法的名称,前面有句点, 比如

.方法

结果是调用以点为参数的方法的值 接收器,dot.Method()

方法调用可以链接并与字段和键组合 到任何深度:

.Field1.Key1.Method1.Field2.Key2.Method2

因此,考虑到这一点,我写了以下内容:

主程序包
进口(
“字节”
“fmt”
“html/模板”
“网络/邮件”
“操作系统”
)
键入EmailAddress结构{mail.Address}
类型emailFormatter结构{
来自电子邮件地址
电邮地址
}
var tmpl=template.Must(template.New(“示例文本”).Parse(“From:{{.From.String}}\r”+`
收件人:{{.To.String}`+“\r”+`
内容类型:text/html`+“\r”+`
主题:示例文本“+”\r\n\r“+`
示例文本
示例文本
`));
func main(){
收件人:=电子邮件地址{
邮寄地址{
地址:“em@i.l",
姓名:“,
},
}
发件人:=电子邮件地址{
邮寄地址{
地址:“否-reply@test.quest",
姓名:“,
},
}
fmt.Println(to.String())//输出(按预期)”
fmt.Println(from.String())//输出(按预期)”
f:=电子邮件格式化程序{
致:致,,
From:From,,
}
var buff bytes.Buffer
如果错误:=tmpl.Execute(&buff,f);错误!=nil{
fmt.Printf(“错误:%v\n”,错误)
操作系统退出(1)
}
fmt.Println(buff.String())
}
我已经分别验证了调用
EmailAddress.String
是完全合法的,所以我不明白为什么它的唯一输出是:

Error: template: Sample Text:1:13: executing "Sample Text" at <.From.String>: can't evaluate field String in type main.EmailAddress
由于是用指针接收器定义的,因此需要将
mail.Address
的“可寻址”实例传递给模板,以便能够执行该方法

您可以通过传入指向
f
的指针来完成此操作

if err := tmpl.Execute(&buff, &f); err != nil {
    panic(err)
}
或者,您可以通过传入指向
电子邮件地址的指针来执行此操作

type emailFormatter struct {
    From *EmailAddress
    To   *EmailAddress
}

// ...

f := emailFormatter{
    To:   &to,
    From: &from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}
type EmailAddress struct{ *mail.Address }

// ...

to := EmailAddress{
    &mail.Address{
        Address: "em@i.l",
        Name: "",
    },
}
from := EmailAddress{
    &mail.Address{
        Address: "no-reply@test.quest",
        Name: "",
    },
}

f := emailFormatter{
    To:   to,
    From: from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}
或者通过传递指向
mail.Address
的指针

type emailFormatter struct {
    From *EmailAddress
    To   *EmailAddress
}

// ...

f := emailFormatter{
    To:   &to,
    From: &from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}
type EmailAddress struct{ *mail.Address }

// ...

to := EmailAddress{
    &mail.Address{
        Address: "em@i.l",
        Name: "",
    },
}
from := EmailAddress{
    &mail.Address{
        Address: "no-reply@test.quest",
        Name: "",
    },
}

f := emailFormatter{
    To:   to,
    From: from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}

请注意,您不需要在Go代码中执行此操作的原因是编译器在那里为您执行此操作

例如:

fmt.Println(to.String())
变成:

fmt.Println((&to).String())
如果方法集(类型)为x,则方法调用x.m()有效 包含m,参数列表可以指定给参数列表 m如果x是可寻址的,并且&x的方法集包含m,则x.m()是 (&x).m()的简写形式

由于是用指针接收器定义的,因此需要将
mail.Address
的“可寻址”实例传递给模板,以便能够执行该方法

您可以通过传入指向
f
的指针来完成此操作

if err := tmpl.Execute(&buff, &f); err != nil {
    panic(err)
}
或者,您可以通过传入指向
电子邮件地址的指针来执行此操作

type emailFormatter struct {
    From *EmailAddress
    To   *EmailAddress
}

// ...

f := emailFormatter{
    To:   &to,
    From: &from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}
type EmailAddress struct{ *mail.Address }

// ...

to := EmailAddress{
    &mail.Address{
        Address: "em@i.l",
        Name: "",
    },
}
from := EmailAddress{
    &mail.Address{
        Address: "no-reply@test.quest",
        Name: "",
    },
}

f := emailFormatter{
    To:   to,
    From: from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}
或者通过传递指向
mail.Address
的指针

type emailFormatter struct {
    From *EmailAddress
    To   *EmailAddress
}

// ...

f := emailFormatter{
    To:   &to,
    From: &from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}
type EmailAddress struct{ *mail.Address }

// ...

to := EmailAddress{
    &mail.Address{
        Address: "em@i.l",
        Name: "",
    },
}
from := EmailAddress{
    &mail.Address{
        Address: "no-reply@test.quest",
        Name: "",
    },
}

f := emailFormatter{
    To:   to,
    From: from,
}

// ...

if err := tmpl.Execute(&buff, f); err != nil {
    panic(err)
}

请注意,您不需要在Go代码中执行此操作的原因是编译器在那里为您执行此操作

例如:

fmt.Println(to.String())
变成:

fmt.Println((&to).String())
如果方法集(类型)为x,则方法调用x.m()有效 包含m,参数列表可以指定给参数列表 m如果x是可寻址的,并且&x的方法集包含m,则x.m()是 (&x).m()的简写形式


因为
String
不是在
EmailAddress
上定义的,它是在
EmailAddress.Address
上定义的。那么为什么我可以在上面调用
EmailAddress.String
呢?我相信这是一个指针接收器问题。如果将
设置为
*电子邮件地址
,会发生什么情况?。。。或者只是将
&f
而不是
f
传递到
Execute
,或者只是将
&f
而不是
f
传递到
Execute
”-就是这样,@mkopriva你想写答案吗?因为
电子邮件地址上没有定义
字符串
,它是在
EmailAddress.Address
上定义的。那么为什么我可以在上面调用
EmailAddress.String
?我相信这是一个指针接收器问题。如果将
设置为
*电子邮件地址
,会发生什么情况?。。。或者只需将
&f
而不是
f
传递到
Execute
,或者只需将
&f
而不是
f
传递到
Execute
”-就这样,@mkopriva你想写一个答案吗?