在Golang模板中使用struct方法

huangapple go评论117阅读模式
英文:

Using struct method in Golang template

问题

在Go模板中,结构体方法通常与公共结构体属性以相同的方式调用,但在这种情况下却不起作用:http://play.golang.org/p/xV86xwJnjA

  1. {{with index . 0}}
  2. {{.FirstName}} {{.LastName}} is {{.SquareAge}} years old.
  3. {{end}}

错误信息:

  1. 执行“person”时出错,错误位置为<.SquareAge>: SquareAge不是main.Person结构体类型的字段

在{{$person}}的例子中也存在同样的问题:

  1. {{$person := index . 0}}
  2. {{$person.FirstName}} {{$person.LastName}} is
  3. {{$person.SquareAge}} years old.

相比之下,以下代码可以正常工作:

  1. {{range .}}
  2. {{.FirstName}} {{.LastName}} is {{.SquareAge}} years old.
  3. {{end}}

如何在{{with}}和{{$person}}的例子中调用SquareAge()方法?

英文:

Struct methods in Go templates are usually called same way as public struct properties but in this case it just doesn't work: http://play.golang.org/p/xV86xwJnjA

  1. {{with index . 0}}
  2. {{.FirstName}} {{.LastName}} is {{.SquareAge}} years old.
  3. {{end}}

Error:

  1. executing "person" at <.SquareAge>: SquareAge is not a field
  2. of struct type main.Person

Same problem with:

  1. {{$person := index . 0}}
  2. {{$person.FirstName}} {{$person.LastName}} is
  3. {{$person.SquareAge}} years old.

In constrast, this works:

  1. {{range .}}
  2. {{.FirstName}} {{.LastName}} is {{.SquareAge}} years old.
  3. {{end}}

How to call SquareAge() method in {{with}} and {{$person}} examples?

答案1

得分: 13

如先前在https://stackoverflow.com/questions/10200178/call-a-method-from-a-go-template中所回答的,该方法的定义如下:

  1. func (p *Person) SquareAge() int {
  2. return p.Age * p.Age
  3. }

该方法仅适用于类型*Person

由于在SquareAge方法中不会改变Person对象,你可以将接收器从p *Person更改为p Person,这样它就可以与你之前的切片一起使用。

或者,如果你将以下代码:

  1. var people = []Person{
  2. {"John", "Smith", 22},
  3. {"Alice", "Smith", 25},
  4. {"Bob", "Baker", 24},
  5. }

替换为:

  1. var people = []*Person{
  2. {"John", "Smith", 22},
  3. {"Alice", "Smith", 25},
  4. {"Bob", "Baker", 24},
  5. }

它也会起作用。

可工作示例1:http://play.golang.org/p/NzWupgl8Km

可工作示例2:http://play.golang.org/p/lN5ySpbQw1

英文:

As previously answered in https://stackoverflow.com/questions/10200178/call-a-method-from-a-go-template, the method as defined by

  1. func (p *Person) SquareAge() int {
  2. return p.Age * p.Age
  3. }

is only available on type *Person.

Since you don't mutate the Person object in the SquareAge method, you could just change the receiver from p *Person to p Person, and it would work with your previous slice.

Alternatively, if you replace

  1. var people = []Person{
  2. {"John", "Smith", 22},
  3. {"Alice", "Smith", 25},
  4. {"Bob", "Baker", 24},
  5. }

with

  1. var people = []*Person{
  2. {"John", "Smith", 22},
  3. {"Alice", "Smith", 25},
  4. {"Bob", "Baker", 24},
  5. }

It'll work as well.

Working example #1: http://play.golang.org/p/NzWupgl8Km

Working example #2: http://play.golang.org/p/lN5ySpbQw1

huangapple
  • 本文由 发表于 2014年12月6日 06:15:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/27325544.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定