func groupByChan(dataChan interface{}, f interface{}) (result interface{}) { fType := reflect.TypeOf(f) fInType := fType.In(0) fRetType := fType.Out(0) sliceOfFInTypes := reflect.SliceOf(fInType) resultValue := reflect.MakeMap(reflect.MapOf(fRetType, sliceOfFInTypes)) fVal := reflect.ValueOf(f) chanValue := reflect.ValueOf(dataChan) value, ok := chanValue.Recv() for ok { idx := fVal.Call([]reflect.Value{value})[0] existingValue := resultValue.MapIndex(idx) if !existingValue.IsValid() { existingValue = reflect.MakeSlice(sliceOfFInTypes, 0, defaultCapacity) } existingValue = reflect.Append(existingValue, value) resultValue.SetMapIndex(idx, existingValue) value, ok = chanValue.Recv() } result = resultValue.Interface() return }
func (p Pages) GroupBy(key string, order ...string) (PagesGroup, error) { if len(p) < 1 { return nil, nil } direction := "asc" if len(order) > 0 && (strings.ToLower(order[0]) == "desc" || strings.ToLower(order[0]) == "rev" || strings.ToLower(order[0]) == "reverse") { direction = "desc" } ppt := reflect.TypeOf(&Page{}) ft, ok := ppt.Elem().FieldByName(key) if !ok { return nil, errors.New("No such field in Page struct") } tmp := reflect.MakeMap(reflect.MapOf(ft.Type, reflect.SliceOf(ppt))) for _, e := range p { ppv := reflect.ValueOf(e) fv := ppv.Elem().FieldByName(key) if !tmp.MapIndex(fv).IsValid() { tmp.SetMapIndex(fv, reflect.MakeSlice(reflect.SliceOf(ppt), 0, 0)) } tmp.SetMapIndex(fv, reflect.Append(tmp.MapIndex(fv), ppv)) } var r []PageGroup for _, k := range sortKeys(tmp.MapKeys(), direction) { r = append(r, PageGroup{Key: k.Interface(), Pages: tmp.MapIndex(k).Interface().([]*Page)}) } return r, nil }
// toReflectType converts the DataType to reflect.Type. func toReflectType(dtype DataType) reflect.Type { switch dtype.Kind() { case BooleanKind: return reflect.TypeOf(true) case IntegerKind: return reflect.TypeOf(int(0)) case NumberKind: return reflect.TypeOf(float64(0)) case StringKind: return reflect.TypeOf("") case DateTimeKind: return reflect.TypeOf(time.Time{}) case ObjectKind, UserTypeKind, MediaTypeKind: return reflect.TypeOf(map[string]interface{}{}) case ArrayKind: return reflect.SliceOf(toReflectType(dtype.ToArray().ElemType.Type)) case HashKind: hash := dtype.ToHash() // avoid complication: not allow object as the hash key var ktype reflect.Type if !hash.KeyType.Type.IsObject() { ktype = toReflectType(hash.KeyType.Type) } else { ktype = reflect.TypeOf([]interface{}{}).Elem() } return reflect.MapOf(ktype, toReflectType(hash.ElemType.Type)) default: return reflect.TypeOf([]interface{}{}).Elem() } }
func (d *mapAsMapDecoder) decode(dv, sv reflect.Value) { dt := dv.Type() dv.Set(reflect.MakeMap(reflect.MapOf(dt.Key(), dt.Elem()))) var mapKey reflect.Value var mapElem reflect.Value keyType := dv.Type().Key() elemType := dv.Type().Elem() for _, sElemKey := range sv.MapKeys() { var dElemKey reflect.Value var dElemVal reflect.Value if !mapKey.IsValid() { mapKey = reflect.New(keyType).Elem() } else { mapKey.Set(reflect.Zero(keyType)) } dElemKey = mapKey if !mapElem.IsValid() { mapElem = reflect.New(elemType).Elem() } else { mapElem.Set(reflect.Zero(elemType)) } dElemVal = mapElem d.keyDec(dElemKey, sElemKey) d.elemDec(dElemVal, sv.MapIndex(sElemKey)) dv.SetMapIndex(dElemKey, dElemVal) } }
func (w *walker) Map(m reflect.Value) error { t := m.Type() newMap := reflect.MakeMap(reflect.MapOf(t.Key(), t.Elem())) w.cs = append(w.cs, newMap) w.valPush(newMap) return nil }
func byOutputMap(iterable interface{}, field string, fn string, slices bool) (itr reflect.Value, f reflect.StructField, out reflect.Value, err error) { itr = reflect.ValueOf(iterable) if itr.Kind() != reflect.Slice && itr.Kind() != reflect.Array { err = fmt.Errorf("first argument to %s must be slice or array, not %T", fn, iterable) return } elem := itr.Type().Elem() s := elem for s.Kind() == reflect.Ptr { s = s.Elem() } if s.Kind() != reflect.Struct { err = fmt.Errorf("first argument to %s must contain structs or pointers to structs, not %v", fn, elem) return } var ok bool f, ok = s.FieldByName(field) if !ok { err = fmt.Errorf("type %v does not have a field named %q", elem, field) return } if slices { elem = reflect.SliceOf(elem) } mapType := reflect.MapOf(f.Type, elem) out = reflect.MakeMap(mapType) return }
// tysubst attempts to substitute all type variables within a single return // type with their corresponding Go type from the type environment. // // tysubst will panic if a type variable is unbound, or if it encounters a // type that cannot be dynamically created. Such types include arrays, // functions and structs. (A limitation of the `reflect` package.) func (rt returnType) tysubst(typ reflect.Type) reflect.Type { if tyname := tyvarName(typ); len(tyname) > 0 { if thetype, ok := rt.tyenv[tyname]; !ok { rt.panic("Unbound type variable %s.", tyname) } else { return thetype } } switch typ.Kind() { case reflect.Array: rt.panic("Cannot dynamically create Array types.") case reflect.Chan: return reflect.ChanOf(typ.ChanDir(), rt.tysubst(typ.Elem())) case reflect.Func: rt.panic("Cannot dynamically create Function types.") case reflect.Interface: rt.panic("TODO") case reflect.Map: return reflect.MapOf(rt.tysubst(typ.Key()), rt.tysubst(typ.Elem())) case reflect.Ptr: return reflect.PtrTo(rt.tysubst(typ.Elem())) case reflect.Slice: return reflect.SliceOf(rt.tysubst(typ.Elem())) case reflect.Struct: rt.panic("Cannot dynamically create Struct types.") case reflect.UnsafePointer: rt.panic("Cannot dynamically create unsafe.Pointer types.") } // We've covered all the composite types, so we're only left with // base types. return typ }
// If op is Operator of "[]T", type of f must be "func(T) T2". // And GroupBy(f) returns value of "map[T2] []T" func (op *Op) GroupBy(f interface{}) interface{} { vs := reflect.ValueOf(op.Slice) vf := reflect.ValueOf(f) tf := vf.Type() if tf.NumIn() != 1 { panic("Number of Argument must be 1") } if tf.NumOut() != 1 { panic("Number of return value must be 1") } tif := tf.In(0) tof := tf.Out(0) if tif != vs.Type().Elem() { panic("Mismatch function type") } len := vs.Len() vom := reflect.MakeMap(reflect.MapOf(tof, vs.Type())) for i := 0; i < len; i++ { v := vs.Index(i) vk := vf.Call([]reflect.Value{v})[0] vi := vom.MapIndex(vk) if vi.IsValid() { vom.SetMapIndex(vk, reflect.Append(vi, v)) } else { vom.SetMapIndex(vk, reflect.Append(reflect.MakeSlice(vs.Type(), 0, len), v)) } } return vom.Interface() }
func goType(t *TypeInfo) reflect.Type { switch t.Type { case TypeVarchar, TypeAscii, TypeInet: return reflect.TypeOf(*new(string)) case TypeBigInt, TypeCounter: return reflect.TypeOf(*new(int64)) case TypeTimestamp: return reflect.TypeOf(*new(time.Time)) case TypeBlob: return reflect.TypeOf(*new([]byte)) case TypeBoolean: return reflect.TypeOf(*new(bool)) case TypeFloat: return reflect.TypeOf(*new(float32)) case TypeDouble: return reflect.TypeOf(*new(float64)) case TypeInt: return reflect.TypeOf(*new(int)) case TypeDecimal: return reflect.TypeOf(*new(*inf.Dec)) case TypeUUID, TypeTimeUUID: return reflect.TypeOf(*new(UUID)) case TypeList, TypeSet: return reflect.SliceOf(goType(t.Elem)) case TypeMap: return reflect.MapOf(goType(t.Key), goType(t.Elem)) case TypeVarint: return reflect.TypeOf(*new(*big.Int)) default: return nil } }
func (p Pages) GroupBy(key, order string) ([]PageGroup, error) { if len(p) < 1 { return nil, nil } if order != "asc" && order != "desc" { return nil, errors.New("order argument must be 'asc' or 'desc'") } ppt := reflect.TypeOf(&Page{}) ft, ok := ppt.Elem().FieldByName(key) if !ok { return nil, errors.New("No such field in Page struct") } tmp := reflect.MakeMap(reflect.MapOf(ft.Type, reflect.SliceOf(ppt))) for _, e := range p { ppv := reflect.ValueOf(e) fv := ppv.Elem().FieldByName(key) if !tmp.MapIndex(fv).IsValid() { tmp.SetMapIndex(fv, reflect.MakeSlice(reflect.SliceOf(ppt), 0, 0)) } tmp.SetMapIndex(fv, reflect.Append(tmp.MapIndex(fv), ppv)) } var r []PageGroup for _, k := range sortKeys(tmp.MapKeys(), order) { r = append(r, PageGroup{Key: k.Interface(), Data: tmp.MapIndex(k).Interface().([]*Page)}) } return r, nil }
func Uniq(source, selector interface{}) interface{} { if selector == nil { selector = func(value, _ interface{}) Facade { return Facade{reflect.ValueOf(value)} } } var mapRV reflect.Value var arrRV reflect.Value each(source, selector, func(resRV, valueRv, _ reflect.Value) bool { if !mapRV.IsValid() { mapRT := reflect.MapOf(resRV.Type(), reflect.TypeOf(false)) mapRV = reflect.MakeMap(mapRT) arrRT := reflect.SliceOf(valueRv.Type()) arrRV = reflect.MakeSlice(arrRT, 0, 0) } mapValueRV := mapRV.MapIndex(resRV) if !mapValueRV.IsValid() { mapRV.SetMapIndex(resRV, reflect.ValueOf(true)) arrRV = reflect.Append(arrRV, valueRv) } return false }) if mapRV.IsValid() { return arrRV.Interface() } return nil }
// MakeMap examines the key type from a Hash and create a map with builtin type if possible. // The idea is to avoid generating map[interface{}]interface{}, which cannot be handled by json.Marshal. func (h *Hash) MakeMap(pair map[interface{}]interface{}) interface{} { if !h.KeyType.Type.IsPrimitive() { // well, a type can't be handled by json.Marshal... not much we can do return pair } if len(pair) == 0 { // figure out the map type manually switch h.KeyType.Type.Kind() { case BooleanKind: return map[bool]interface{}{} case IntegerKind: return map[int]interface{}{} case NumberKind: return map[float64]interface{}{} case StringKind: return map[string]interface{}{} case DateTimeKind: return map[time.Time]interface{}{} default: return pair } } var newMap reflect.Value for key, value := range pair { rkey, rvalue := reflect.ValueOf(key), reflect.ValueOf(value) if !newMap.IsValid() { newMap = reflect.MakeMap(reflect.MapOf(rkey.Type(), rvalue.Type())) } newMap.SetMapIndex(rkey, rvalue) } return newMap.Interface() }
func (r *RuleWrapper) GetReflectType() (reflect.Type, error) { if r.Struct != nil && r.Struct.Interface { typ, ok := r.Parent.GetReflectInterface(r.Ctx) if !ok { return nil, kerr.New("QGUVEUTXAN", "Type interface for %s not found", r.Parent.Id.Value()) } return typ, nil } if c, ok := r.Interface.(CollectionRule); ok { itemsRule := c.GetItemsRule() if itemsRule != nil { items := WrapRule(r.Ctx, itemsRule) itemsType, err := items.GetReflectType() if err != nil { return nil, kerr.Wrap("LMKEHHWHKL", err) } if r.Parent.NativeJsonType(r.Ctx) == J_MAP { return reflect.MapOf(reflect.TypeOf(""), itemsType), nil } return reflect.SliceOf(itemsType), nil } } typ, ok := r.Parent.GetReflectType(r.Ctx) if !ok { return nil, kerr.New("DLAJJPJDPL", "Type %s not found", r.Parent.Id.Value()) } return typ, nil }
func (s *Common) ExtendMap(i interface{}, with interface{}) { name := fmt.Sprintf("%v", i) m, ok := s.data[name] if !ok { m = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(""), reflect.TypeOf(with))) } m.SetMapIndex(reflect.ValueOf(name), reflect.ValueOf(with)) s.data[name] = m }
func (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error { valType := val.Type() valKeyType := valType.Key() valElemType := valType.Elem() // Make a new map to hold our result mapType := reflect.MapOf(valKeyType, valElemType) valMap := reflect.MakeMap(mapType) // Check input type dataVal := reflect.Indirect(reflect.ValueOf(data)) if dataVal.Kind() != reflect.Map { // Accept empty array/slice instead of an empty map in weakly typed mode if d.config.WeaklyTypedInput && (dataVal.Kind() == reflect.Slice || dataVal.Kind() == reflect.Array) && dataVal.Len() == 0 { val.Set(valMap) return nil } else { return fmt.Errorf("'%s' expected a map, got '%s'", name, dataVal.Kind()) } } // Accumulate errors errors := make([]string, 0) for _, k := range dataVal.MapKeys() { fieldName := fmt.Sprintf("%s[%s]", name, k) // First decode the key into the proper type currentKey := reflect.Indirect(reflect.New(valKeyType)) if err := d.decode(fieldName, k.Interface(), currentKey); err != nil { errors = appendErrors(errors, err) continue } // Next decode the data into the proper type v := dataVal.MapIndex(k).Interface() currentVal := reflect.Indirect(reflect.New(valElemType)) if err := d.decode(fieldName, v, currentVal); err != nil { errors = appendErrors(errors, err) continue } valMap.SetMapIndex(currentKey, currentVal) } // Set the built up map to the value val.Set(valMap) // If we had errors, return those if len(errors) > 0 { return &Error{errors} } return nil }
// AsMap converts given map into other map func AsMap(v interface{}, key reflect.Type, val reflect.Type, add func(to reflect.Value, key reflect.Value, val reflect.Value)) reflect.Value { res := reflect.MakeMap(reflect.MapOf(key, val)) r := reflect.ValueOf(v) switch r.Kind() { case reflect.Map: for _, k := range r.MapKeys() { add(res, k, r.MapIndex(k)) } } return res }
// MapTypeParser 定义了序列类型解析逻辑 func MapTypeParser(st p.State) (interface{}, error) { key, err := p.Between(p.Str("map["), p.Chr(']'), TypeParser)(st) if err != nil { return nil, err } value, err := TypeParser(st) if err != nil { return nil, err } return reflect.MapOf(key.(Type).Type, value.(Type).Type), nil }
func (d *decoder) decodeInterface(name string, v *MrbValue, result reflect.Value) error { var set reflect.Value redecode := true switch t := v.Type(); t { case TypeHash: var temp map[string]interface{} tempVal := reflect.ValueOf(temp) result := reflect.MakeMap( reflect.MapOf( reflect.TypeOf(""), tempVal.Type().Elem())) set = result case TypeArray: var temp []interface{} tempVal := reflect.ValueOf(temp) result := reflect.MakeSlice( reflect.SliceOf(tempVal.Type().Elem()), 0, 0) set = result case TypeFalse: fallthrough case TypeTrue: var result bool set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) case TypeFixnum: var result int set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) case TypeFloat: var result float64 set = reflect.Indirect(reflect.New(reflect.TypeOf(result))) case TypeString: set = reflect.Indirect(reflect.New(reflect.TypeOf(""))) default: return fmt.Errorf( "%s: cannot decode into interface: %s", name, t) } // Set the result to what its supposed to be, then reset // result so we don't reflect into this method anymore. result.Set(set) if redecode { // Revisit the node so that we can use the newly instantiated // thing and populate it. if err := d.decode(name, v, result); err != nil { return err } } return nil }
func decodeIntoMap(name string, o *Object, result reflect.Value) error { if o.Type() != ObjectTypeObject { return fmt.Errorf("%s: not an object type, can't decode to map", name) } resultType := result.Type() resultElemType := resultType.Elem() resultKeyType := resultType.Key() if resultKeyType.Kind() != reflect.String { return fmt.Errorf("%s: map must have string keys", name) } // Make a map to store our result resultMap := result if result.IsNil() { resultMap = reflect.MakeMap( reflect.MapOf(resultKeyType, resultElemType)) } outerIter := o.Iterate(false) defer outerIter.Close() for outer := outerIter.Next(); outer != nil; outer = outerIter.Next() { iter := outer.Iterate(true) defer iter.Close() for elem := iter.Next(); elem != nil; elem = iter.Next() { fieldName := fmt.Sprintf("%s[%s]", name, elem.Key()) key := reflect.ValueOf(elem.Key()) // The value we have to be decode val := reflect.Indirect(reflect.New(resultElemType)) // If we have a pre-existing value in the map, use that oldVal := resultMap.MapIndex(key) if oldVal.IsValid() { val.Set(oldVal) } err := decode(fieldName, elem, val) elem.Close() if err != nil { return err } resultMap.SetMapIndex(key, val) } } // Set the final result result.Set(resultMap) return nil }
func (w *walker) Map(m reflect.Value) error { if w.ignoring() { return nil } // Get the type for the map t := m.Type() mapType := reflect.MapOf(t.Key(), t.Elem()) // Create the map. If the map itself is nil, then just make a nil map var newMap reflect.Value if m.IsNil() { newMap = reflect.Indirect(reflect.New(mapType)) } else { newMap = reflect.MakeMap(reflect.MapOf(t.Key(), t.Elem())) } w.cs = append(w.cs, newMap) w.valPush(newMap) return nil }
func (t *Job) Reduce(args Args, reply *int) error { go func() { r := new(task.ReduceCollector) elem := reflect.TypeOf(r).Elem() key := elem.Field(0).Type value := reflect.SliceOf(elem.Field(1).Type) m := reflect.MapOf(key, value) mp := reflect.MakeMap(m).Interface() combine(t.decodeReduce(t.path), mp) mpv := reflect.ValueOf(mp) keys := mpv.MapKeys() length := len(keys) chinr := make(chan CombineCollector, length) choutr := make(chan task.ReduceCollector, length) chfinr := make(chan bool) for i := 0; i < t.NumReduce; i++ { go reduceRoutine(chinr, choutr, chfinr) } for i := range keys { key := keys[i] val := mpv.MapIndex(key) chinr <- CombineCollector{key.Interface(), val.Interface()} } conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", t.Master, t.ReduceDataPort)) if err != nil { log.Fatal("Connection error ", err) } encoder := gob.NewEncoder(conn) err = encoder.Encode(&Port) err = encoder.Encode(&length) for _ = range keys { redData := <-choutr err = encoder.Encode(&redData) } if err != nil { panic(err) } conn.Close() for i := 0; i < t.NumReduce; i++ { chfinr <- true } }() *reply = 0 return nil }
// ContainsSameElements compares, without taking order on the // first level, the contents of two slices of the same type. // The elements of the slice must have comparisons defined, // otherwise a panic will result. func ContainsSameElements(s1, s2 interface{}) bool { // TODO add support for chans when needed. // Preliminary checks to weed out incompatible inputs. if reflect.TypeOf(s1).Kind() != reflect.Slice || reflect.TypeOf(s2).Kind() != reflect.Slice { panic("received non-slice argument") } if reflect.TypeOf(s1) != reflect.TypeOf(s2) { panic("received slices with incompatible types") } // Create a map that keeps a count of how often we see // each element in the slices. m := reflect.MakeMap(reflect.MapOf(reflect.TypeOf(s1).Elem(), reflect.TypeOf(uint64(0)))) // Get the actual slices we are comparing. rs1 := reflect.ValueOf(s1) rs2 := reflect.ValueOf(s2) var zeroValue reflect.Value if rs1.Len() != rs2.Len() { return false } // Fill the counting hash map using the first slice. for i := 0; i < rs1.Len(); i++ { v := rs1.Index(i) k := m.MapIndex(v) if k == zeroValue { // The entry did not exist, so the new count is 1. m.SetMapIndex(v, reflect.ValueOf(uint64(1))) } else { m.SetMapIndex(v, reflect.ValueOf(k.Uint()+uint64(1))) } } // Compare the counts from s1 against the second slice. for i := 0; i < rs2.Len(); i++ { v := rs2.Index(i) k := m.MapIndex(v) if k == zeroValue { return false } else if k.Uint() == 1 { // Setting the zero value removes the entry. m.SetMapIndex(v, zeroValue) } else { m.SetMapIndex(v, reflect.ValueOf(k.Uint()-uint64(1))) } } // If all went well until here, the map is now empty. return m.Len() == 0 }
// MapTypeParserExt 定义了带环境的映射类型解析逻辑 func MapTypeParserExt(env Env) p.P { return func(st p.State) (interface{}, error) { key, err := p.Between(p.Str("map["), p.Chr(']'), ExtTypeParser(env))(st) if err != nil { return nil, err } value, err := ExtTypeParser(env)(st) if err != nil { return nil, err } return reflect.MapOf(key.(Type).Type, value.(Type).Type), nil } }
// The subkeyType() function is used to choose types when none is specified // by the input. When overwriting into an interface{}, a concrete type is // chosen here. It will be a map[string]interface{}, []interface{}, or string // depending on whether the subkey is a field, index, or terminal. func (k fieldKey) subkeyType() reflect.Type { var i interface{} switch k.subkey.(type) { case fieldKey: return reflect.MapOf(reflect.TypeOf("string"), reflect.TypeOf(&i).Elem()) case indexKey: return reflect.SliceOf(reflect.TypeOf(&i).Elem()) case terminalKey: return reflect.TypeOf("") default: panic("unreachable") } }
func (d *Decoder) decodeMap(n int) (interface{}, error) { var err error var keyType, valType reflect.Type keys := [16]interface{}{} keyType = nil vals := [16]interface{}{} valType = nil for i := 0; i < n; i++ { keys[i], err = d.decode() if err != nil { return nil, err } vals[i], err = d.decode() if err != nil { return nil, err } _keyType := reflect.TypeOf(keys[i]) if _keyType.Kind() == reflect.Map { return nil, fmt.Errorf("Map is don't be map key.") } if keyType == nil { keyType = _keyType } else if keyType != _keyType { keyType = _interfaceType } _valType := reflect.TypeOf(vals[i]) if valType == nil { valType = _valType } else if valType != _valType { valType = _interfaceType } } if keyType == nil { keyType = _interfaceType } if valType == nil { valType = _interfaceType } result := reflect.MakeMap(reflect.MapOf(keyType, valType)) for i := 0; i < n; i++ { result.SetMapIndex(reflect.ValueOf(keys[i]), reflect.ValueOf(vals[i])) } return result.Interface(), nil }
// StreamJSON uses the supplied client to POST the given proto request as JSON // to the supplied streaming grpc-gw endpoint; the response type serves only to // create the values passed to the callback (which is invoked for every message // in the stream with a value of the supplied response type masqueraded as an // interface). func StreamJSON( httpClient http.Client, path string, request proto.Message, dest proto.Message, callback func(proto.Message), ) error { str, err := (&jsonpb.Marshaler{}).MarshalToString(request) if err != nil { return err } resp, err := httpClient.Post(path, JSONContentType, strings.NewReader(str)) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, err := ioutil.ReadAll(resp.Body) return errors.Errorf("status: %s, body: %s, error: %s", resp.Status, b, err) } // grpc-gw/runtime's JSONpb {en,de}coder is pretty half-baked. Essentially // we must pass a *map[string]*concreteType or it won't work (in // particular, using a struct or replacing `*concreteType` with either // `concreteType` or `proto.Message` leads to errors). This method should do // a decent enough job at encapsulating this away; should this change, we // should consider cribbing and fixing up the marshaling code. m := reflect.New(reflect.MapOf(reflect.TypeOf(""), reflect.TypeOf(dest))) // TODO(tschottdorf,tamird): We have cribbed parts of this object to deal // with varying proto imports, and should technically use them here. We can // get away with not cribbing more here for now though. marshaler := runtime.JSONPb{} decoder := marshaler.NewDecoder(resp.Body) for { if err := decoder.Decode(m.Interface()); err == io.EOF { break } else if err != nil { return err } v := m.Elem().MapIndex(reflect.ValueOf("result")) if !v.IsValid() { // TODO(tschottdorf): recover actual JSON. return errors.Errorf("unexpected JSON response: %+v", m) } callback(v.Interface().(proto.Message)) } return nil }
func ArrayColumnMap(data interface{}, columnNames string) interface{} { //提取信息 name := Explode(columnNames, ",") nameInfo := []arrayColumnMapInfo{} dataValue := reflect.ValueOf(data) dataType := dataValue.Type().Elem() for _, singleName := range name { singleField, ok := getFieldByName(dataType, singleName) if !ok { panic(dataType.Name() + " struct has not field " + singleName) } nameInfo = append(nameInfo, arrayColumnMapInfo{ Index: singleField.Index, Type: singleField.Type, }) } prevType := dataType for i := len(nameInfo) - 1; i >= 0; i-- { nameInfo[i].MapType = reflect.MapOf( nameInfo[i].Type, prevType, ) prevType = nameInfo[i].MapType } //整合map result := reflect.MakeMap(nameInfo[0].MapType) dataLen := dataValue.Len() for i := 0; i != dataLen; i++ { singleValue := dataValue.Index(i) prevValue := result for singleNameIndex, singleNameInfo := range nameInfo { var nextValue reflect.Value singleField := singleValue.FieldByIndex(singleNameInfo.Index) nextValue = prevValue.MapIndex(singleField) if !nextValue.IsValid() { if singleNameIndex+1 < len(nameInfo) { nextValue = reflect.MakeMap(nameInfo[singleNameIndex+1].MapType) } else { nextValue = singleValue } prevValue.SetMapIndex(singleField, nextValue) } prevValue = nextValue } } return result.Interface() }
func Serialize(input interface{}) string { switch reflect.ValueOf(input).Kind() { case reflect.Int: return strconv.Itoa(input.(int)) case reflect.Uint8: return Serialize(int(input.(uint8))) case reflect.Int8: return Serialize(int(input.(int8))) case reflect.Uint16: return Serialize(int(input.(uint16))) case reflect.Int16: return Serialize(int(input.(int16))) case reflect.Uint32: return Serialize(int64(input.(uint32))) case reflect.Int32: return Serialize(int(input.(int32))) case reflect.Int64: return strconv.FormatInt(input.(int64), 10) case reflect.Float64: return strconv.FormatFloat(input.(float64), 'f', 6, 64) case reflect.String: return "\"" + strings.Replace(input.(string), "\"", "\\\"", -1) + "\"" case reflect.Map: t := reflect.TypeOf(input) v := reflect.ValueOf(input) it := reflect.TypeOf((*interface{})(nil)).Elem() m := reflect.MakeMap(reflect.MapOf(t.Key(), it)) for _, mk := range v.MapKeys() { m.SetMapIndex(mk, v.MapIndex(mk)) } return mapSerialize(m.Interface().(map[string]interface{})) case reflect.Slice: s := reflect.ValueOf(input) ret := make([]interface{}, s.Len()) for i := 0; i < s.Len(); i++ { ret[i] = s.Index(i).Interface() } return arraySerialize(ret) case reflect.Struct: return structSerialize(input) default: panic("Attempt to serialize unsupported type.") } }
// GroupByParam groups by the given page parameter key's value and with the given order. // Valid values for order is asc, desc, rev and reverse. func (p Pages) GroupByParam(key string, order ...string) (PagesGroup, error) { if len(p) < 1 { return nil, nil } direction := "asc" if len(order) > 0 && (strings.ToLower(order[0]) == "desc" || strings.ToLower(order[0]) == "rev" || strings.ToLower(order[0]) == "reverse") { direction = "desc" } var tmp reflect.Value var keyt reflect.Type for _, e := range p { param := e.GetParam(key) if param != nil { if _, ok := param.([]string); !ok { keyt = reflect.TypeOf(param) tmp = reflect.MakeMap(reflect.MapOf(keyt, reflect.SliceOf(pagePtrType))) break } } } if !tmp.IsValid() { return nil, errors.New("There is no such a param") } for _, e := range p { param := e.getParam(key, false) if param == nil || reflect.TypeOf(param) != keyt { continue } v := reflect.ValueOf(param) if !tmp.MapIndex(v).IsValid() { tmp.SetMapIndex(v, reflect.MakeSlice(reflect.SliceOf(pagePtrType), 0, 0)) } tmp.SetMapIndex(v, reflect.Append(tmp.MapIndex(v), reflect.ValueOf(e))) } var r []PageGroup for _, k := range sortKeys(tmp.MapKeys(), direction) { r = append(r, PageGroup{Key: k.Interface(), Pages: tmp.MapIndex(k).Interface().([]*Page)}) } return r, nil }
// Memoize takes a function and returns a function of the same type. The // returned function remembers the return value(s) of the function call. // Any pointer values will be used as an address, so functions that modify // their arguments or programs that modify returned values will not work. // // The returned function is safe to call from multiple goroutines if the // original function is. Panics are handled, so calling panic from a function // will call panic with the same value on future invocations with the same // arguments. // // The arguments to the function must be of comparable types. Slices, maps, // functions, and structs or arrays that contain slices, maps, or functions // cause a runtime panic if they are arguments to a memoized function. // See also: https://golang.org/ref/spec#Comparison_operators // // As a special case, variadic functions (func(x, y, ...z)) are allowed. func Memoize(fn interface{}) interface{} { v := reflect.ValueOf(fn) t := v.Type() keyType := reflect.ArrayOf(t.NumIn(), interfaceType) cache := reflect.MakeMap(reflect.MapOf(keyType, valueType)) var mtx sync.Mutex return reflect.MakeFunc(t, func(args []reflect.Value) (results []reflect.Value) { key := reflect.New(keyType).Elem() for i, v := range args { if i == len(args)-1 && t.IsVariadic() { a := reflect.New(reflect.ArrayOf(v.Len(), v.Type().Elem())).Elem() for j, l := 0, v.Len(); j < l; j++ { a.Index(j).Set(v.Index(j)) } v = a } vi := v.Interface() key.Index(i).Set(reflect.ValueOf(&vi).Elem()) } mtx.Lock() val := cache.MapIndex(key) if val.IsValid() { mtx.Unlock() c := val.Interface().(*call) <-c.wait if c.panicked.IsValid() { panic(c.panicked.Interface()) } return c.results } w := make(chan struct{}) c := &call{wait: w} cache.SetMapIndex(key, reflect.ValueOf(c)) mtx.Unlock() panicked := true defer func() { if panicked { p := recover() c.panicked = reflect.ValueOf(p) close(w) panic(p) } }() if t.IsVariadic() { results = v.CallSlice(args) } else { results = v.Call(args) } panicked = false c.results = results close(w) return }).Interface() }