mirror of
https://github.com/golang/go
synced 2024-11-21 20:54:45 -07:00
exp/template: allow an empty interface value to be the target of range, etc.
We extract the concrete value inside. R=golang-dev, adg CC=golang-dev https://golang.org/cl/4677041
This commit is contained in:
parent
381a555f40
commit
a33cc423b4
@ -183,6 +183,10 @@ func (s *state) evalPipeline(data reflect.Value, pipe []*commandNode) reflect.Va
|
|||||||
value := reflect.Value{}
|
value := reflect.Value{}
|
||||||
for _, cmd := range pipe {
|
for _, cmd := range pipe {
|
||||||
value = s.evalCommand(data, cmd, value) // previous value is this one's final arg.
|
value = s.evalCommand(data, cmd, value) // previous value is this one's final arg.
|
||||||
|
// If the object has type interface{}, dig down one level to the thing inside.
|
||||||
|
if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 {
|
||||||
|
value = reflect.ValueOf(value.Interface()) // lovely!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,8 @@ type T struct {
|
|||||||
MSI map[string]int
|
MSI map[string]int
|
||||||
MSIone map[string]int // one element, for deterministic output
|
MSIone map[string]int // one element, for deterministic output
|
||||||
MSIEmpty map[string]int
|
MSIEmpty map[string]int
|
||||||
|
// Empty interface; used to see if we can dig inside one.
|
||||||
|
EmptyInterface interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple methods with and without arguments.
|
// Simple methods with and without arguments.
|
||||||
@ -79,14 +81,15 @@ type U struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tVal = &T{
|
var tVal = &T{
|
||||||
I: 17,
|
I: 17,
|
||||||
U16: 16,
|
U16: 16,
|
||||||
X: "x",
|
X: "x",
|
||||||
U: &U{"v"},
|
U: &U{"v"},
|
||||||
SI: []int{3, 4, 5},
|
SI: []int{3, 4, 5},
|
||||||
SB: []bool{true, false},
|
SB: []bool{true, false},
|
||||||
MSI: map[string]int{"one": 1, "two": 2, "three": 3},
|
MSI: map[string]int{"one": 1, "two": 2, "three": 3},
|
||||||
MSIone: map[string]int{"one": 1},
|
MSIone: map[string]int{"one": 1},
|
||||||
|
EmptyInterface: []int{7, 8},
|
||||||
}
|
}
|
||||||
|
|
||||||
type execTest struct {
|
type execTest struct {
|
||||||
@ -187,6 +190,7 @@ var execTests = []execTest{
|
|||||||
{"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true},
|
{"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true},
|
||||||
{"range map else", "{{range .MSI | .MSort}}-{{.}}-{{else}}EMPTY{{end}}", "-one--three--two-", tVal, true},
|
{"range map else", "{{range .MSI | .MSort}}-{{.}}-{{else}}EMPTY{{end}}", "-one--three--two-", tVal, true},
|
||||||
{"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
|
{"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
|
||||||
|
{"range empty interface", "{{range .EmptyInterface}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
|
||||||
// Error handling.
|
// Error handling.
|
||||||
{"error method, error", "{{.EPERM true}}", "", tVal, false},
|
{"error method, error", "{{.EPERM true}}", "", tVal, false},
|
||||||
{"error method, no error", "{{.EPERM false}}", "false", tVal, true},
|
{"error method, no error", "{{.EPERM false}}", "false", tVal, true},
|
||||||
|
Loading…
Reference in New Issue
Block a user