func (association *Association) Append(values ...interface{}) *Association { scope := association.Scope field := scope.IndirectValue().FieldByName(association.Column) for _, value := range values { reflectvalue := reflect.ValueOf(value) if reflectvalue.Kind() == reflect.Ptr { if reflectvalue.Elem().Kind() == reflect.Struct { if field.Type().Elem().Kind() == reflect.Ptr { field.Set(reflect.Append(field, reflectvalue)) } else if field.Type().Elem().Kind() == reflect.Struct { field.Set(reflect.Append(field, reflectvalue.Elem())) } } else if reflectvalue.Elem().Kind() == reflect.Slice { if field.Type().Elem().Kind() == reflect.Ptr { field.Set(reflect.AppendSlice(field, reflectvalue)) } else if field.Type().Elem().Kind() == reflect.Struct { field.Set(reflect.AppendSlice(field, reflectvalue.Elem())) } } } else if reflectvalue.Kind() == reflect.Struct && field.Type().Elem().Kind() == reflect.Struct { field.Set(reflect.Append(field, reflectvalue)) } else if reflectvalue.Kind() == reflect.Slice && field.Type().Elem() == reflectvalue.Type().Elem() { field.Set(reflect.AppendSlice(field, reflectvalue)) } else { association.err(errors.New("invalid association type")) } } scope.callCallbacks(scope.db.parent.callback.updates) return association.err(scope.db.Error) }
func (s *sequenceType) Build(i *Injector) (Binding, error) { binding, err := Annotate(s.v).Build(i) if err != nil { return Binding{}, err } if binding.Provides.Kind() != reflect.Slice { return Binding{}, fmt.Errorf("Sequence() must be bound to a slice not %s", binding.Provides) } next, ok := i.bindings[binding.Provides] return Binding{ Provides: binding.Provides, Requires: binding.Requires, Build: func() (interface{}, error) { out := reflect.MakeSlice(binding.Provides, 0, 0) if ok { v, err := next.Build() if err != nil { return nil, err } out = reflect.AppendSlice(out, reflect.ValueOf(v)) } v, err := binding.Build() if err != nil { return nil, err } out = reflect.AppendSlice(out, reflect.ValueOf(v)) return out.Interface(), nil }, }, nil }
// DeleteCopy removes the element of the slice at a given index. // The returned slice references a new array, the original // array and all referencing slices are un-altered. // // The returned slice will be the same type as the given slice, but // stored in an interface{}. // // Uses reflection to perform this action on slices of any type. // Will panic if: // - slice argument is not a slice type // - idx is not in the range 0 .. len(slice)-1 // // Equivalent to: // slice = append(append(make([]T,0,len(slice)-1),slice[:idx]...),slice[idx+1]...) func DeleteCopy(slice interface{}, index int) interface{} { sliceVal := checkDelete(slice, index) begin := sliceVal.Slice(0, index) end := sliceVal.Slice(index+1, sliceVal.Len()) tmp := reflect.MakeSlice(sliceVal.Type(), 0, sliceVal.Len()-1) return reflect.AppendSlice(reflect.AppendSlice(tmp, begin), end).Interface() }
// InsertCopy adds an element to a slice at a given index. Always allocates // a new slice, and never modifies the original memory. // // The returned slice will be the same type as the given slice, but // stored in an interface{}. // // Uses reflection to perform this action on slices of any type. // Will panic if: // - slice argument is not a slice type // - slice argument's element type doesn't match item's type // - idx is not in the range 0 .. len(slice) // // Equivalent to: // begin, end := slice[:idx], slice[idx:] // slice = append(append(append(make([]T,0,len(slice)+1), begin...),item),end...) func InsertCopy(slice interface{}, index int, item interface{}) interface{} { sliceVal, itemVal := checkInsert(slice, index, item) begin := sliceVal.Slice(0, index) end := sliceVal.Slice(index, sliceVal.Len()) out := reflect.MakeSlice(sliceVal.Type(), 0, sliceVal.Len()+1) out = reflect.AppendSlice(reflect.Append(reflect.AppendSlice(out, begin), itemVal), end) return out.Interface() }
func (f *protoFuzzer) Fuzz(v reflect.Value) { if !v.CanSet() { return } switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: f.FuzzInt(v) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: f.FuzzUint(v) case reflect.String: str := "" for i := 0; i < v.Len(); i++ { str = str + string(' '+rune(f.r.Intn(94))) } v.SetString(str) return case reflect.Ptr: if !v.IsNil() { f.Fuzz(v.Elem()) } return case reflect.Slice: mode := f.r.Intn(3) switch { case v.Len() > 0 && mode == 0: // fuzz entry f.Fuzz(v.Index(f.r.Intn(v.Len()))) case v.Len() > 0 && mode == 1: // remove entry entry := f.r.Intn(v.Len()) pre := v.Slice(0, entry) post := v.Slice(entry+1, v.Len()) v.Set(reflect.AppendSlice(pre, post)) default: // add entry entry := reflect.MakeSlice(v.Type(), 1, 1) f.Fuzz(entry) // XXX fill all fields v.Set(reflect.AppendSlice(v, entry)) } return case reflect.Struct: f.Fuzz(v.Field(f.r.Intn(v.NumField()))) return case reflect.Map: // TODO fuzz map default: panic(fmt.Sprintf("Not fuzzing %v %+v", v.Kind(), v)) } }
func main() { var a []int var value reflect.Value = reflect.ValueOf(&a) //判断指针是否指向内存地址 if !value.CanSet() { value = value.Elem() //使指针指向内存地址 } value = reflect.AppendSlice(value, reflect.ValueOf([]int{1, 2})) //支持切片 value = reflect.AppendSlice(value, reflect.ValueOf([]int{3, 4, 5, 6, 7, 8, 9})) //支持切片 fmt.Println(value.Kind(), value.Slice(0, value.Len()).Interface()) ///// >> slice [1 2 3 4 5 6 7 8 9] }
func (s *sliceShrink) Next() (interface{}, bool) { if s.chunkLength == 0 { return nil, false } value := reflect.AppendSlice(reflect.MakeSlice(s.original.Type(), 0, s.length-s.chunkLength), s.original.Slice(0, s.offset)) s.offset += s.chunkLength if s.offset < s.length { value = reflect.AppendSlice(value, s.original.Slice(s.offset, s.length)) } else { s.offset = 0 s.chunkLength >>= 1 } return value.Interface(), true }
// loadSlice loads url and decodes it into a []elemType, returning the []elemType and error. func loadSlice(url string, elemType interface{}) (interface{}, error) { t := reflect.TypeOf(elemType) result := reflect.New(reflect.SliceOf(t)).Elem() // result is []elemType link := url for link != "" { req, err := http.NewRequest("GET", link, nil) if err != nil { return result.Interface(), err } resp, err := http.DefaultClient.Do(req) if err != nil { return result.Interface(), err } if resp.StatusCode > 299 { lr := io.LimitReader(resp.Body, 1024) bs, _ := ioutil.ReadAll(lr) resp.Body.Close() return result.Interface(), fmt.Errorf("http.Get: %v (%s)", resp.Status, bs) } tmp := reflect.New(reflect.SliceOf(t)) // tmp is *[]elemType err = json.NewDecoder(resp.Body).Decode(tmp.Interface()) resp.Body.Close() if err != nil { return result.Interface(), err } result = reflect.AppendSlice(result, tmp.Elem()) link = parseRel(resp.Header.Get("Link"), "next") } return result.Interface(), nil }
func deStructSlice(dataValue reflect.Value) (interface{}, interface{}, map[string]interface{}) { if dataValue.Kind() == reflect.Uint8 { newDataValue := reflect.MakeSlice(dataValue.Type(), dataValue.Len(), dataValue.Cap()) newDataValue = reflect.AppendSlice(newDataValue, dataValue) return newDataValue.Interface(), newDataValue.Interface(), nil } //TODO if the type inside the slice is not a struct, recreate the slice with the same definition newData := make([]interface{}, dataValue.Len()) flatData := make(map[string]interface{}) for i := 0; i < dataValue.Len(); i++ { subDataValue := dataValue.Index(i) key := strconv.Itoa(i) fieldCopy, fieldScalar, fieldMap := deStructValue(subDataValue) newData[i] = fieldCopy if fieldScalar != nil { flatData[key] = fieldScalar } for fieldMapKey, fieldMapValue := range fieldMap { flatData[key+"."+fieldMapKey] = fieldMapValue } } return newData, nil, flatData }
func (node *tagAppendNode) Execute(ctx *p2.ExecutionContext, writer p2.TemplateWriter) *p2.Error { var values []interface{} var reflectValues reflect.Value if o := ctx.Public[node.name]; nil != o { values, _ = o.([]interface{}) if nil == values { reflectValues = reflect.ValueOf(o) if reflectValues.Kind() == reflect.Ptr { reflectValues = reflectValues.Elem() } if reflectValues.Kind() != reflect.Slice { return ctx.Error("'"+node.name+"' isn't a slice.", nil) } } } for _, ev := range node.objectEvaluators { obj, err := ev.Evaluate(ctx) if err != nil { return err } if reflectValues.IsNil() { values = append(values, obj) } else { reflectValues = reflect.AppendSlice(reflectValues, reflect.ValueOf(obj)) } } if reflectValues.IsNil() { ctx.Public[node.name] = values } else { ctx.Public[node.name] = reflectValues.Interface() } return nil }
func Delete(element interface{}, slice interface{}) bool { valElement := reflect.ValueOf(element) typSlice := reflect.TypeOf(slice) valSlice := reflect.ValueOf(slice) if !valElement.IsValid() || !valSlice.IsValid() { return false } switch typSlice.Kind() { case reflect.Slice: sliceLen := valSlice.Len() for idx := 0; idx < sliceLen; idx++ { val := valSlice.Index(idx) if !val.IsValid() { continue } if val.Interface() == valElement.Interface() { if idx == sliceLen-1 { valSlice = valSlice.Slice(0, idx) } else { valSlice = reflect.AppendSlice(valSlice.Slice(0, idx), valSlice.Slice(idx+1, sliceLen-1)) } } } case reflect.Map: } return false }
func mergeValue(values []reflect.Value) reflect.Value { values = removeZeroValues(values) l := len(values) if l == 0 { return reflect.Value{} } sample := values[0] mergeable := isMergeable(sample) t := sample.Type() if mergeable { t = t.Elem() } value := reflect.MakeSlice(reflect.SliceOf(t), 0, 0) for i := 0; i < l; i++ { if !values[i].IsValid() { continue } if mergeable { value = reflect.AppendSlice(value, values[i]) } else { value = reflect.Append(value, values[i]) } } return value }
// A very limited merge. Merges the fields named in the fields parameter, // replacing most values, but appending to arrays. func mergeStruct(base, overlay interface{}, fields []string) error { baseValue := reflect.ValueOf(base).Elem() overlayValue := reflect.ValueOf(overlay).Elem() if baseValue.Kind() != reflect.Struct { return fmt.Errorf("Tried to merge something that wasn't a struct: type %v was %v", baseValue.Type(), baseValue.Kind()) } if baseValue.Type() != overlayValue.Type() { return fmt.Errorf("Tried to merge two different types: %v and %v", baseValue.Type(), overlayValue.Type()) } for _, field := range fields { overlayFieldValue := findField(field, overlayValue) if !overlayFieldValue.IsValid() { return fmt.Errorf("could not find field in %v matching %v", overlayValue.Type(), field) } baseFieldValue := findField(field, baseValue) if overlayFieldValue.Kind() == reflect.Slice { baseFieldValue.Set(reflect.AppendSlice(baseFieldValue, overlayFieldValue)) } else { baseFieldValue.Set(overlayFieldValue) } } return nil }
// Stitch provides a function that may be used by polymer types to implement Stitcher. // It makes use of reflection and so may be slower than type-specific implementations. // This is the reference implementation and should be used to compare type-specific // implementation against in testing. func Stitch(pol interface{}, offset int, f feat.FeatureSet) (s interface{}, err error) { t := interval.NewTree() var i *interval.Interval for _, feature := range f { i, err = interval.New(emptyString, feature.Start, feature.End, 0, nil) if err != nil { return } else { t.Insert(i) } } pv := reflect.ValueOf(pol) pLen := pv.Len() end := pLen + offset span, err := interval.New(emptyString, offset, end, 0, nil) if err != nil { panic("Sequence.End() < Sequence.Start()") } fs, _ := t.Flatten(span, 0, 0) l := 0 for _, seg := range fs { l += util.Min(seg.End(), end) - util.Max(seg.Start(), offset) } tv := reflect.MakeSlice(pv.Type(), 0, l) for _, seg := range fs { tv = reflect.AppendSlice(tv, pv.Slice(util.Max(seg.Start()-offset, 0), util.Min(seg.End()-offset, pLen))) } return tv.Interface(), nil }
// appendStruct is an internal helper function to AppendConfig. Given two values // of structures (assumed to be the same type), recursively iterate over every // field in the struct, appending slices, recursively appending structs, and // overwriting old values with the new for all other types. Individual fields // are able to override their merge strategy using the "merge" tag. Accepted // values are "new" or "old": "new" uses the new value, "old" uses the old // value. These are currently only used for "ignition.config" and // "ignition.version". func appendStruct(vOld, vNew reflect.Value) reflect.Value { tOld := vOld.Type() vRes := reflect.New(tOld) for i := 0; i < tOld.NumField(); i++ { vfOld := vOld.Field(i) vfNew := vNew.Field(i) vfRes := vRes.Elem().Field(i) switch tOld.Field(i).Tag.Get("merge") { case "old": vfRes.Set(vfOld) continue case "new": vfRes.Set(vfNew) continue } switch vfOld.Type().Kind() { case reflect.Struct: vfRes.Set(appendStruct(vfOld, vfNew)) case reflect.Slice: vfRes.Set(reflect.AppendSlice(vfOld, vfNew)) default: vfRes.Set(vfNew) } } return vRes.Elem() }
// NextPage retrieves a sequence of items from the iterator and appends them // to slicep, which must be a pointer to a slice of the iterator's item type. // Exactly p.pageSize items will be appended, unless fewer remain. // // The first return value is the page token to use for the next page of items. // If empty, there are no more pages. Aside from checking for the end of the // iteration, the returned page token is only needed if the iteration is to be // resumed a later time, in another context (possibly another process). // // The second return value is non-nil if an error occurred. It will never be // the special iterator sentinel value Done. To recognize the end of the // iteration, compare nextPageToken to the empty string. // // It is possible for NextPage to return a single zero-length page along with // an empty page token when there are no more items in the iteration. func (p *Pager) NextPage(slicep interface{}) (nextPageToken string, err error) { p.pageInfo.nextPageCalled = true if p.pageInfo.err != nil { return "", p.pageInfo.err } if p.pageInfo.nextCalled { p.pageInfo.err = errMixed return "", p.pageInfo.err } if p.pageInfo.bufLen() > 0 { return "", errors.New("must call NextPage with an empty buffer") } // The buffer must be empty here, so takeBuf is a no-op. We call it just to get // the buffer's type. wantSliceType := reflect.PtrTo(reflect.ValueOf(p.pageInfo.takeBuf()).Type()) if slicep == nil { return "", errors.New("nil passed to Pager.NextPage") } vslicep := reflect.ValueOf(slicep) if vslicep.Type() != wantSliceType { return "", fmt.Errorf("slicep should be of type %s, got %T", wantSliceType, slicep) } for p.pageInfo.bufLen() < p.pageSize { if err := p.pageInfo.fill(p.pageSize - p.pageInfo.bufLen()); err != nil { p.pageInfo.err = err return "", p.pageInfo.err } if p.pageInfo.Token == "" { break } } e := vslicep.Elem() e.Set(reflect.AppendSlice(e, reflect.ValueOf(p.pageInfo.takeBuf()))) return p.pageInfo.Token, nil }
func AppendValue(dest interface{}, value ...interface{}) (err error) { defer func() { tmperr := recover() err, _ = tmperr.(error) }() if lenval := len(value); lenval > 0 { sliceval := reflect.ValueOf(dest).Elem() newslice := reflect.MakeSlice(sliceval.Type(), 0, lenval) if lenval == 1 { reflect.Append(newslice, reflect.ValueOf(value[0]).Elem()) } else { reflect.AppendSlice(newslice, reflect.ValueOf(value)) } /* for _, val := range value { reflect.Append(newslice, reflect.ValueOf(val).Elem()) } */ sliceval.Set(newslice) } return }
func sliceFromStrings(value interface{}, type_ interface{}) (vs interface{}, err error) { switch value.(type) { case string: sv := value.(string) strs := strings.Split(sv, ",") switch type_.(type) { case string: return strs, err case int: var ivs []int for _, s := range strs { var iv int64 iv, err = strconv.ParseInt(s, 10, 64) if err != nil { err = fmt.Errorf("Cannot parse %v (int)", s) return } ivs = append(ivs, int(iv)) } return ivs, err case float64: var fvs []float64 for _, s := range strs { var fv float64 fv, err = strconv.ParseFloat(s, 64) if err != nil { err = fmt.Errorf("Cannot parse %v (float64)", s) return } fvs = append(fvs, fv) } return fvs, err default: err = fmt.Errorf("Cannot parse %v (%v)", value, reflect.ValueOf(value).Kind()) return } case []string: // var values interface{} for _, sval := range value.([]string) { val, err := sliceFromStrings(sval, type_) if err != nil { return vs, err } // vs = append(vs, val) if reflect.TypeOf(vs) == nil { vs = val } else { vs = reflect.AppendSlice( reflect.ValueOf(vs), reflect.ValueOf(val), ).Interface() } } default: err = fmt.Errorf("Cannot parse %v (%v)", value, reflect.ValueOf(value).Kind()) } return }
// For single values, Add will add (using the + operator) the addend to the existing addend (if found). // Supports numeric values and strings. // // If the first add for a key is an array or slice, then the next value(s) will be appended. func (c *Scratch) Add(key string, newAddend interface{}) (string, error) { var newVal interface{} existingAddend, found := c.values[key] if found { var err error addendV := reflect.ValueOf(existingAddend) if addendV.Kind() == reflect.Slice || addendV.Kind() == reflect.Array { nav := reflect.ValueOf(newAddend) if nav.Kind() == reflect.Slice || nav.Kind() == reflect.Array { newVal = reflect.AppendSlice(addendV, nav).Interface() } else { newVal = reflect.Append(addendV, nav).Interface() } } else { newVal, err = helpers.DoArithmetic(existingAddend, newAddend, '+') if err != nil { return "", err } } } else { newVal = newAddend } c.values[key] = newVal return "", nil // have to return something to make it work with the Go templates }
func (w *overrideWalker) SliceElem(idx int, v reflect.Value) error { if w.depth == 1 && w.currentSectionName == w.o.Section && w.o.Element != "" { w.currentElementName = "" if w.elementKey == "" { return fmt.Errorf("an element key must be specified via the `%s:\",%s<field name>\"` struct tag", structTagKey, elementKeyword) } // Get current element name via field on current value elementField := findFieldByElementKey(v, w.elementKey) if !elementField.IsValid() { return fmt.Errorf("could not find field with name %q on value of type %s", w.elementKey, v.Type()) } if elementField.Kind() != reflect.String { return fmt.Errorf("element key field must be of type string, got %s", elementField.Type()) } w.currentElementName = elementField.String() if w.o.Element == w.currentElementName { if w.o.Delete { // Delete the element from the slice by re-slicing the element out w.currentSlice.Set( reflect.AppendSlice( w.currentSlice.Slice(0, idx), w.currentSlice.Slice(idx+1, w.currentSlice.Len()), ), ) } else { w.elementValue = v } } } return nil }
//复合类型修改示例 func func5() { s := make([]int, 0, 10) v := reflect.ValueOf(&s).Elem() v.SetLen(2) v.Index(0).SetInt(100) v.Index(1).SetInt(200) fmt.Println(v.Interface(), s) v2 := reflect.Append(v, reflect.ValueOf(300)) v2 = reflect.AppendSlice(v2, reflect.ValueOf([]int{400, 500})) fmt.Println(v2.Interface()) //fmt.Println(v2.Interface().([]int)) fmt.Println("-----------------") m := map[string]int{"a": 1} v = reflect.ValueOf(&m).Elem() v.SetMapIndex(reflect.ValueOf("a"), reflect.ValueOf(100)) //update v.SetMapIndex(reflect.ValueOf("b"), reflect.ValueOf(200)) //add fmt.Println(v.Interface().(map[string]int)) }
func decodeSlice(v reflect.Value, x interface{}) { t := v.Type() if t.Elem().Kind() == reflect.Uint8 { // Allow, but don't require, byte slices to be encoded as a single string. if s, ok := x.(string); ok { v.SetBytes([]byte(s)) return } } // NOTE: Implicit indexing is currently done at the parseValues level, // so if if an implicitKey reaches here it will always replace the last. implicit := 0 for k, c := range getNode(x) { var i int if k == implicitKey { i = implicit implicit++ } else { explicit, err := strconv.Atoi(k) if err != nil { panic(k + " is not a valid index for type " + t.String()) } i = explicit implicit = explicit + 1 } // "Extend" the slice if it's too short. if l := v.Len(); i >= l { delta := i - l + 1 v.Set(reflect.AppendSlice(v, reflect.MakeSlice(t, delta, delta))) } decodeValue(v.Index(i), c) } }
func SliceAppendSlice(slice interface{}, sliceToAppend interface{}) interface{} { if reflect.TypeOf(slice).Kind() != reflect.Slice || reflect.TypeOf(sliceToAppend).Kind() != reflect.Slice { panic("wrong type") } newSlice := reflect.ValueOf(slice) newSlice = reflect.AppendSlice(newSlice, reflect.ValueOf(sliceToAppend)) return newSlice.Interface() }
func growSliceValue(v reflect.Value, n int) reflect.Value { diff := n - v.Len() if diff > sliceAllocLimit { diff = sliceAllocLimit } v = reflect.AppendSlice(v, reflect.MakeSlice(v.Type(), diff, diff)) return v }
func DeleteSliceElementVal(sliceVal reflect.Value, idx int) reflect.Value { if idx < 0 || idx >= sliceVal.Len() { return sliceVal } before := sliceVal.Slice(0, idx) after := sliceVal.Slice(idx+1, sliceVal.Len()) sliceVal = reflect.AppendSlice(before, after) return sliceVal }
// FindParallelByCondition executes SELECT query to all of the shards with conditions func (xpr *XormParallel) FindParallelByCondition(listPtr interface{}, cond FindCondition) error { vt := reflect.TypeOf(listPtr) if vt.Kind() != reflect.Ptr { return errors.NewErrArgType("listPtr must be a pointer") } elem := vt.Elem() if elem.Kind() != reflect.Slice && elem.Kind() != reflect.Map { return errors.NewErrArgType("listPtr must be a pointer of slice or map") } // create session with the condition slaves := xpr.orm.Slaves(cond.Table) var sessions []Session for _, slave := range slaves { s := slave.NewSession() for _, w := range cond.Where { s.And(w.Statement, w.Args...) } for _, o := range cond.OrderBy { if o.OrderByDesc { s.Desc(o.Name) } else { s.Asc(o.Name) } } if cond.Limit > 0 { s.Limit(cond.Limit, cond.Offset) } sessions = append(sessions, s) } // execute query var errList []error results := make(chan reflect.Value, len(slaves)) for _, s := range sessions { list := reflect.New(elem) go func(s Session, list reflect.Value) { err := s.Find(list.Interface()) if err != nil { errList = append(errList, err) } results <- list }(s, list) } // wait for the results e := reflect.ValueOf(listPtr).Elem() for range slaves { v := <-results e.Set(reflect.AppendSlice(e, v.Elem())) } if len(errList) > 0 { return errors.NewErrParallelQuery(errList) } return nil }
func mergeAny(out, in reflect.Value) { if in.Type() == protoMessageType { if !in.IsNil() { if out.IsNil() { out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) } else { Merge(out.Interface().(Message), in.Interface().(Message)) } } return } switch in.Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: out.Set(in) case reflect.Ptr: if in.IsNil() { return } if out.IsNil() { out.Set(reflect.New(in.Elem().Type())) } mergeAny(out.Elem(), in.Elem()) case reflect.Slice: if in.IsNil() { return } if in.Type().Elem().Kind() == reflect.Uint8 { // []byte is a scalar bytes field, not a repeated field. // Make a deep copy. // Append to []byte{} instead of []byte(nil) so that we never end up // with a nil result. out.SetBytes(append([]byte{}, in.Bytes()...)) return } n := in.Len() if out.IsNil() { out.Set(reflect.MakeSlice(in.Type(), 0, n)) } switch in.Type().Elem().Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: out.Set(reflect.AppendSlice(out, in)) default: for i := 0; i < n; i++ { x := reflect.Indirect(reflect.New(in.Type().Elem())) mergeAny(x, in.Index(i)) out.Set(reflect.Append(out, x)) } } case reflect.Struct: mergeStruct(out, in) default: // unknown type, so not a protocol buffer log.Printf("proto: don't know how to copy %v", in) } }
func removeAt(index int, s interface{}) interface{} { t, v := reflect.TypeOf(s), reflect.ValueOf(s) cpy := reflect.MakeSlice(t, v.Len(), v.Len()) reflect.Copy(cpy, v) if index == 0 { return cpy.Slice(1, cpy.Len()).Interface() } else { return reflect.AppendSlice(cpy.Slice(0, index), cpy.Slice(index+1, cpy.Len())).Interface() } }
func appendBytes(intSize int, v reflect.Value, b []byte) reflect.Value { length := (len(b) * 8) / intSize sh := &reflect.SliceHeader{} sh.Cap = length sh.Len = length sh.Data = uintptr(unsafe.Pointer(&b[0])) nslice := reflect.NewAt(v.Type(), unsafe.Pointer(sh)).Elem() return reflect.AppendSlice(v, nslice) }
func mergeAny(out, in reflect.Value) { if in.Type() == protoMessageType { if !in.IsNil() { if out.IsNil() { out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) } else { Merge(out.Interface().(Message), in.Interface().(Message)) } } return } switch in.Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: out.Set(in) case reflect.Ptr: if in.IsNil() { return } if out.IsNil() { out.Set(reflect.New(in.Elem().Type())) } mergeAny(out.Elem(), in.Elem()) case reflect.Slice: if in.IsNil() { return } n := in.Len() if out.IsNil() { out.Set(reflect.MakeSlice(in.Type(), 0, n)) } switch in.Type().Elem().Kind() { case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: out.Set(reflect.AppendSlice(out, in)) case reflect.Uint8: // []byte is a scalar bytes field. out.Set(in) default: for i := 0; i < n; i++ { x := reflect.Indirect(reflect.New(in.Type().Elem())) mergeAny(x, in.Index(i)) out.Set(reflect.Append(out, x)) } } case reflect.Struct: mergeStruct(out, in) default: // unknown type, so not a protocol buffer log.Printf("proto: don't know how to copy %v", in) } }