Skip to content

text/template: Methods vs funcs discrepancy #20503

@bep

Description

@bep
▶ go version
go version go1.8.1 darwin/amd64
▶ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/bep/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/n6/s_85mm8d31j6yctssnmn_g1r0000gn/T/go-build150403565=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

The following Go program:

package main

import (
	"bytes"
	"fmt"
	"text/template"
)

type A struct {
	Func func() []string
}

func (A) Method() []string {
	return []string{"c", "d"}
}

func main() {
	a := A{}
	a.Func = a.Method

	for _, v := range a.Method() {
		fmt.Println(">>", v)
	}

	for _, v := range a.Func() {
		fmt.Println(">>", v)
	}

	for _, tpl := range []string{"{{ range .Method  }}{{ . }}{{ end }}", "{{ range .Func  }}{{ . }}{{ end }}"} {

		var buf bytes.Buffer
		tmpl, err := template.New("").Parse(tpl)
		if err != nil {
			panic(err)
		}
		if err := tmpl.Execute(&buf, a); err != nil {
			panic(err)
		}

		fmt.Println(buf.String())
	}

}

Prints

>> c
>> d
>> c
>> d
cd
panic: template: :1:9: executing "" at <.Func>: range can't iterate over 0x10e3320

This is, to me, unexpected behaviour. The method is invoked before it is ranged on, the func not.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions