Quellcode durchsuchen

Reset slice rather than appending to old value.

Fixes #48.
Gustavo Niemeyer vor 11 Jahren
Ursprung
Commit
088598405c
2 geänderte Dateien mit 15 neuen und 4 gelöschten Zeilen
  1. 8 4
      decode.go
  2. 7 0
      decode_test.go

+ 8 - 4
decode.go

@@ -476,27 +476,31 @@ func settableValueOf(i interface{}) reflect.Value {
 }
 
 func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
+	l := len(n.children)
+
 	var iface reflect.Value
 	switch out.Kind() {
 	case reflect.Slice:
-		// okay
+		out.Set(reflect.MakeSlice(out.Type(), l, l))
 	case reflect.Interface:
 		// No type hints. Will have to use a generic sequence.
 		iface = out
-		out = settableValueOf(make([]interface{}, 0))
+		out = settableValueOf(make([]interface{}, l))
 	default:
 		d.terror(n, yaml_SEQ_TAG, out)
 		return false
 	}
 	et := out.Type().Elem()
 
-	l := len(n.children)
+	j := 0
 	for i := 0; i < l; i++ {
 		e := reflect.New(et).Elem()
 		if ok := d.unmarshal(n.children[i], e); ok {
-			out.Set(reflect.Append(out, e))
+			out.Index(j).Set(e)
+			j++
 		}
 	}
+	out.Set(out.Slice(0, j))
 	if iface.IsValid() {
 		iface.Set(out)
 	}

+ 7 - 0
decode_test.go

@@ -879,6 +879,13 @@ func (s *S) TestUnmarshalNull(c *C) {
 	}
 }
 
+func (s *S) TestUnmarshalSliceOnPreset(c *C) {
+	// Issue #48.
+	v := struct{ A []int }{[]int{1}}
+	yaml.Unmarshal([]byte("a: [2]"), &v)
+	c.Assert(v.A, DeepEquals, []int{2})
+}
+
 //var data []byte
 //func init() {
 //	var err error