1
0
mirror of https://github.com/golang/go synced 2024-11-21 21:54:40 -07:00

exp/template: truth for interface values.

Also protect against invalid (zero Value) reflect.Values.

R=rsc, gri
CC=golang-dev
https://golang.org/cl/4810094
This commit is contained in:
Rob Pike 2011-08-11 08:27:16 +10:00
parent 8f3c7497ac
commit 39fa2a5bf2
2 changed files with 9 additions and 3 deletions

View File

@ -148,7 +148,7 @@ func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.
val := s.evalPipeline(dot, pipe)
truth, ok := isTrue(val)
if !ok {
s.errorf("if/with can't use value of type %T", val.Interface())
s.errorf("if/with can't use %v", val)
}
if truth {
if typ == parse.NodeWith {
@ -164,6 +164,10 @@ func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.
// isTrue returns whether the value is 'true', in the sense of not the zero of its type,
// and whether the value has a meaningful truth value.
func isTrue(val reflect.Value) (truth, ok bool) {
if !val.IsValid() {
// Something like var x interface{}, never set. It's a form of nil.
return false, true
}
switch val.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
truth = val.Len() > 0
@ -171,7 +175,7 @@ func isTrue(val reflect.Value) (truth, ok bool) {
truth = val.Bool()
case reflect.Complex64, reflect.Complex128:
truth = val.Complex() != 0
case reflect.Chan, reflect.Func, reflect.Ptr:
case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
truth = !val.IsNil()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
truth = val.Int() != 0

View File

@ -366,7 +366,9 @@ var execTests = []execTest{
// Was taking address of interface field, so method set was empty.
{"bug2", "{{$.NonEmptyInterface.Method0}}", "M0", tVal, true},
// Struct values were not legal in with - mere oversight.
{"bug4", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
{"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
// Nil interface values in if.
{"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true},
}
func zeroArgs() string {