コード例 #1
1
ファイル: encode.go プロジェクト: ossrs/go-oryx-lib
func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	se.arrayEnc(e, v, false)
}
コード例 #2
0
ファイル: decode.go プロジェクト: newthinker/samples
func getSetter(outt reflect.Type, out reflect.Value) Setter {
	setterMutex.RLock()
	style := setterStyle[outt]
	setterMutex.RUnlock()
	if style == setterNone {
		return nil
	}
	if style == setterUnknown {
		setterMutex.Lock()
		defer setterMutex.Unlock()
		if outt.Implements(setterIface) {
			setterStyle[outt] = setterType
		} else if reflect.PtrTo(outt).Implements(setterIface) {
			setterStyle[outt] = setterAddr
		} else {
			setterStyle[outt] = setterNone
			return nil
		}
		style = setterStyle[outt]
	}
	if style == setterAddr {
		if !out.CanAddr() {
			return nil
		}
		out = out.Addr()
	} else if outt.Kind() == reflect.Ptr && out.IsNil() {
		out.Set(reflect.New(outt.Elem()))
	}
	return out.Interface().(Setter)
}
コード例 #3
0
ファイル: decode.go プロジェクト: MG-RAST/Shock
func (f *decFnInfo) kSlice(rv reflect.Value) {
	// A slice can be set from a map or array in stream.
	currEncodedType := f.dd.currentEncodedType()

	switch currEncodedType {
	case valueTypeBytes, valueTypeString:
		if f.ti.rtid == uint8SliceTypId || f.ti.rt.Elem().Kind() == reflect.Uint8 {
			if bs2, changed2 := f.dd.decodeBytes(rv.Bytes()); changed2 {
				rv.SetBytes(bs2)
			}
			return
		}
	}

	if shortCircuitReflectToFastPath && rv.CanAddr() {
		switch f.ti.rtid {
		case intfSliceTypId:
			f.d.decSliceIntf(rv.Addr().Interface().(*[]interface{}), currEncodedType, f.array)
			return
		case uint64SliceTypId:
			f.d.decSliceUint64(rv.Addr().Interface().(*[]uint64), currEncodedType, f.array)
			return
		case int64SliceTypId:
			f.d.decSliceInt64(rv.Addr().Interface().(*[]int64), currEncodedType, f.array)
			return
		case strSliceTypId:
			f.d.decSliceStr(rv.Addr().Interface().(*[]string), currEncodedType, f.array)
			return
		}
	}

	containerLen, containerLenS := decContLens(f.dd, currEncodedType)

	// an array can never return a nil slice. so no need to check f.array here.

	if rv.IsNil() {
		rv.Set(reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS))
	}

	if containerLen == 0 {
		return
	}

	if rvcap, rvlen := rv.Len(), rv.Cap(); containerLenS > rvcap {
		if f.array { // !rv.CanSet()
			decErr(msgDecCannotExpandArr, rvcap, containerLenS)
		}
		rvn := reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS)
		if rvlen > 0 {
			reflect.Copy(rvn, rv)
		}
		rv.Set(rvn)
	} else if containerLenS > rvlen {
		rv.SetLen(containerLenS)
	}

	for j := 0; j < containerLenS; j++ {
		f.d.decodeValue(rv.Index(j))
	}
}
コード例 #4
0
ファイル: return_handler.go プロジェクト: RezaDKhan/terraform
func defaultReturnHandler() ReturnHandler {
	return func(ctx *Context, vals []reflect.Value) {
		rv := ctx.GetVal(inject.InterfaceOf((*http.ResponseWriter)(nil)))
		resp := rv.Interface().(http.ResponseWriter)
		var respVal reflect.Value
		if len(vals) > 1 && vals[0].Kind() == reflect.Int {
			resp.WriteHeader(int(vals[0].Int()))
			respVal = vals[1]
		} else if len(vals) > 0 {
			respVal = vals[0]

			if isError(respVal) {
				err := respVal.Interface().(error)
				if err != nil {
					ctx.internalServerError(ctx, err)
				}
				return
			} else if canDeref(respVal) {
				if respVal.IsNil() {
					return // Ignore nil error
				}
			}
		}
		if canDeref(respVal) {
			respVal = respVal.Elem()
		}
		if isByteSlice(respVal) {
			resp.Write(respVal.Bytes())
		} else {
			resp.Write([]byte(respVal.String()))
		}
	}
}
コード例 #5
0
ファイル: bson_decode.go プロジェクト: teopeurt/go-mongo
func decodeMapStringInterface(d *decodeState, kind int, v reflect.Value) {
	if kind != kindDocument {
		d.saveErrorAndSkip(kind, v.Type())
	}
	if v.IsNil() {
		v.Set(reflect.MakeMap(v.Type()))
	}

	var m map[string]interface{}
	switch mm := v.Interface().(type) {
	case map[string]interface{}:
		m = mm
	case M:
		m = (map[string]interface{})(mm)
	}

	offset := d.beginDoc()
	for {
		kind, name := d.scanKindName()
		if kind == 0 {
			break
		}
		if kind == kindNull {
			continue
		}
		m[string(name)] = d.decodeValueInterface(kind)
	}
	d.endDoc(offset)
}
コード例 #6
0
ファイル: params.go プロジェクト: hortonworks/kubernetes-yarn
func isZero(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.Func, reflect.Map, reflect.Slice:
		return v.IsNil()
	case reflect.Array:
		z := true
		for i := 0; i < v.Len(); i++ {
			z = z && isZero(v.Index(i))
		}
		return z
	case reflect.Struct:
		if v.Type() == reflect.TypeOf(t) {
			if v.Interface().(time.Time).IsZero() {
				return true
			}
			return false
		}
		z := true
		for i := 0; i < v.NumField(); i++ {
			z = z && isZero(v.Field(i))
		}
		return z
	}
	// Compare other types directly:
	z := reflect.Zero(v.Type())
	return v.Interface() == z.Interface()
}
コード例 #7
0
ファイル: queryutil.go プロジェクト: ClearcodeHQ/Go-Forward
func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error {
	switch value := r.Interface().(type) {
	case string:
		v.Set(name, value)
	case []byte:
		if !r.IsNil() {
			v.Set(name, base64.StdEncoding.EncodeToString(value))
		}
	case bool:
		v.Set(name, strconv.FormatBool(value))
	case int64:
		v.Set(name, strconv.FormatInt(value, 10))
	case int:
		v.Set(name, strconv.Itoa(value))
	case float64:
		v.Set(name, strconv.FormatFloat(value, 'f', -1, 64))
	case float32:
		v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32))
	case time.Time:
		const ISO8601UTC = "2006-01-02T15:04:05Z"
		v.Set(name, value.UTC().Format(ISO8601UTC))
	default:
		return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
	}
	return nil
}
コード例 #8
0
ファイル: encode.go プロジェクト: ossrs/go-oryx-lib
func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	pe.elemEnc(e, v.Elem(), quoted)
}
コード例 #9
0
ファイル: encode.go プロジェクト: eswdd/bosun
func (f encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v interface{}, proceed bool) {
	if indir == 0 {
		v = rv.Interface()
	} else if indir == -1 {
		// If a non-pointer was passed to Encode(), then that value is not addressable.
		// Take addr if addresable, else copy value to an addressable value.
		if rv.CanAddr() {
			v = rv.Addr().Interface()
		} else {
			rv2 := reflect.New(rv.Type())
			rv2.Elem().Set(rv)
			v = rv2.Interface()
			// fmt.Printf("rv.Type: %v, rv2.Type: %v, v: %v\n", rv.Type(), rv2.Type(), v)
		}
	} else {
		for j := int8(0); j < indir; j++ {
			if rv.IsNil() {
				f.ee.EncodeNil()
				return
			}
			rv = rv.Elem()
		}
		v = rv.Interface()
	}
	return v, true
}
コード例 #10
0
ファイル: db.go プロジェクト: seacoastboy/goku
// scan the value by fields, and set to v
func rawScanStruct(v reflect.Value, fields []string, scanner rowScaner) (err error) {
	if v.IsNil() {
		e := fmt.Sprintf("struct can not be nil, but got %#v", v.Interface())
		return errors.New(e)
	}
	dest := make([]interface{}, len(fields))
	for v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	// Loop over column names and find field in s to bind to
	// based on column name. all returned columns must match
	// a field in the s struct
	for x, fieldName := range fields {
		f := v.FieldByName(fieldName)
		if f == zeroVal {
			e := fmt.Sprintf("Scanner: No field %s in type %s",
				fieldName, v.Type())
			return errors.New(e)
		} else {
			dest[x] = f.Addr().Interface()
		}
	}

	err = scanner.Scan(dest...)
	return
}
コード例 #11
0
ファイル: decode.go プロジェクト: amasses/form
func decodeMap(v reflect.Value, x interface{}) {
	t := v.Type()
	if v.IsNil() {
		v.Set(reflect.MakeMap(t))
	}
	for k, c := range getNode(x) {
		i := reflect.New(t.Key()).Elem()
		decodeValue(i, k)

		w := v.MapIndex(i)
		if w.IsValid() { // We have an actual element value to decode into.
			if w.Kind() == reflect.Interface {
				w = w.Elem()
			}
			w = reflect.New(w.Type()).Elem()
		} else if t.Elem().Kind() != reflect.Interface { // The map's element type is concrete.
			w = reflect.New(t.Elem()).Elem()
		} else {
			// The best we can do here is to decode as either a string (for scalars) or a map[string]interface {} (for the rest).
			// We could try to guess the type based on the string (e.g. true/false => bool) but that'll get ugly fast,
			// especially if we have to guess the kind (slice vs. array vs. map) and index type (e.g. string, int, etc.)
			switch c.(type) {
			case node:
				w = reflect.MakeMap(stringMapType)
			case string:
				w = reflect.New(stringType).Elem()
			default:
				panic("value is neither node nor string")
			}
		}

		decodeValue(w, c)
		v.SetMapIndex(i, w)
	}
}
コード例 #12
0
ファイル: exec.go プロジェクト: bibbyflyaway/go
// validateType guarantees that the value is valid and assignable to the type.
func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value {
	if !value.IsValid() {
		if typ == nil || canBeNil(typ) {
			// An untyped nil interface{}. Accept as a proper nil value.
			return reflect.Zero(typ)
		}
		s.errorf("invalid value; expected %s", typ)
	}
	if typ != nil && !value.Type().AssignableTo(typ) {
		if value.Kind() == reflect.Interface && !value.IsNil() {
			value = value.Elem()
			if value.Type().AssignableTo(typ) {
				return value
			}
			// fallthrough
		}
		// Does one dereference or indirection work? We could do more, as we
		// do with method receivers, but that gets messy and method receivers
		// are much more constrained, so it makes more sense there than here.
		// Besides, one is almost always all you need.
		switch {
		case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
			value = value.Elem()
			if !value.IsValid() {
				s.errorf("dereference of nil pointer of type %s", typ)
			}
		case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
			value = value.Addr()
		default:
			s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
		}
	}
	return value
}
コード例 #13
0
ファイル: exec.go プロジェクト: bibbyflyaway/go
// isTrue reports 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
	case reflect.Bool:
		truth = val.Bool()
	case reflect.Complex64, reflect.Complex128:
		truth = val.Complex() != 0
	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
	case reflect.Float32, reflect.Float64:
		truth = val.Float() != 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		truth = val.Uint() != 0
	case reflect.Struct:
		truth = true // Struct values are always true.
	default:
		return
	}
	return truth, true
}
コード例 #14
0
func assertValid(vObj reflect.Value) error {
	if !vObj.IsValid() {
		return nil
	}

	if obj, ok := vObj.Interface().(interface {
		AssertValid() error
	}); ok && !(vObj.Kind() == reflect.Ptr && vObj.IsNil()) {
		if err := obj.AssertValid(); err != nil {
			return err
		}
	}

	switch vObj.Kind() {
	case reflect.Ptr:
		return assertValid(vObj.Elem())
	case reflect.Struct:
		return assertStructValid(vObj)
	case reflect.Slice:
		for i := 0; i < vObj.Len(); i++ {
			if err := assertValid(vObj.Index(i)); err != nil {
				return err
			}
		}
	}

	return nil
}
コード例 #15
0
ファイル: print.go プロジェクト: serussell/kgc
// NotNilFilter returns true for field values that are not nil;
// it returns false otherwise.
func NotNilFilter(_ string, value reflect.Value) bool {
	//v, ok := value.(interface {
	//	IsNil() bool
	//})
	//return !ok || !v.IsNil()
	return value.IsNil()
}
コード例 #16
0
ファイル: encode.go プロジェクト: ossrs/go-oryx-lib
func interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) {
	if v.IsNil() {
		e.WriteString("null")
		return
	}
	e.reflectValue(v.Elem())
}
コード例 #17
0
ファイル: encode.go プロジェクト: eswdd/bosun
func (f encFnInfo) kInterface(rv reflect.Value) {
	if rv.IsNil() {
		f.ee.EncodeNil()
		return
	}
	f.e.encodeValue(rv.Elem(), encFn{})
}
コード例 #18
0
ファイル: encode.go プロジェクト: eswdd/bosun
func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, proceed bool) {
LOOP:
	for {
		switch rv.Kind() {
		case reflect.Ptr, reflect.Interface:
			if rv.IsNil() {
				e.e.EncodeNil()
				return
			}
			rv = rv.Elem()
			continue LOOP
		case reflect.Slice, reflect.Map:
			if rv.IsNil() {
				e.e.EncodeNil()
				return
			}
		case reflect.Invalid, reflect.Func:
			e.e.EncodeNil()
			return
		}
		break
	}

	return rv, true
}
コード例 #19
0
ファイル: queryutil.go プロジェクト: ClearcodeHQ/Go-Forward
func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
	// If it's empty, generate an empty value
	if !value.IsNil() && value.Len() == 0 {
		v.Set(prefix, "")
		return nil
	}

	// check for unflattened list member
	if !q.isEC2 && tag.Get("flattened") == "" {
		prefix += ".member"
	}

	for i := 0; i < value.Len(); i++ {
		slicePrefix := prefix
		if slicePrefix == "" {
			slicePrefix = strconv.Itoa(i + 1)
		} else {
			slicePrefix = slicePrefix + "." + strconv.Itoa(i+1)
		}
		if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil {
			return err
		}
	}
	return nil
}
コード例 #20
0
ファイル: decode.go プロジェクト: nsf/libtorgo
func (d *decoder) parse_unmarshaler(v reflect.Value) bool {
	m, ok := v.Interface().(Unmarshaler)
	if !ok {
		// T doesn't work, try *T
		if v.Kind() != reflect.Ptr && v.CanAddr() {
			m, ok = v.Addr().Interface().(Unmarshaler)
			if ok {
				v = v.Addr()
			}
		}
	}
	if ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
		if d.read_one_value() {
			err := m.UnmarshalBencode(d.buf.Bytes())
			d.buf.Reset()
			if err != nil {
				panic(&UnmarshalerError{v.Type(), err})
			}
			return true
		}
		d.buf.Reset()
	}

	return false
}
コード例 #21
0
ファイル: unmarshal.go プロジェクト: QuocHuy7a10/Arianrhod
func (p *Decoder) unmarshalDictionary(pval *plistValue, val reflect.Value) {
	typ := val.Type()
	switch val.Kind() {
	case reflect.Struct:
		tinfo, err := getTypeInfo(typ)
		if err != nil {
			panic(err)
		}

		subvalues := pval.value.(*dictionary).m
		for _, finfo := range tinfo.fields {
			p.unmarshal(subvalues[finfo.name], finfo.value(val))
		}
	case reflect.Map:
		if val.IsNil() {
			val.Set(reflect.MakeMap(typ))
		}

		subvalues := pval.value.(*dictionary).m
		for k, sval := range subvalues {
			keyv := reflect.ValueOf(k).Convert(typ.Key())
			mapElem := val.MapIndex(keyv)
			if !mapElem.IsValid() {
				mapElem = reflect.New(typ.Elem()).Elem()
			}

			p.unmarshal(sval, mapElem)
			val.SetMapIndex(keyv, mapElem)
		}
	default:
		panic(&incompatibleDecodeTypeError{typ, pval.kind})
	}
}
コード例 #22
0
ファイル: mapper.go プロジェクト: unrolled/jet
func (m *mapper) unpackValue(keys []string, values []interface{}, out reflect.Value) error {
	switch out.Kind() {
	case reflect.Ptr:
		if out.IsNil() {
			out.Set(reflect.New(out.Type().Elem()))
		}
		return m.unpackValue(keys, values, reflect.Indirect(out))
	case reflect.Slice:
		if keys == nil {
			return m.unpackSimple(nil, values, out)
		} else {
			return m.unpackSlice(keys, values, out)
		}
	case reflect.Struct:
		return m.unpackStruct(keys, values, out)
	case reflect.Map:
		if keys == nil {
			return m.unpackSimple(nil, values, out)
		} else {
			return m.unpackMap(keys, values, out)
		}
	default:
		return m.unpackSimple(nil, values, out)
	}
	return fmt.Errorf("cannot unpack result to %T (%s)", out, out.Kind())
}
コード例 #23
0
ファイル: encode.go プロジェクト: yschu7/go_test
// All protocol buffer fields are nillable, but be careful.
func isNil(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return v.IsNil()
	}
	return false
}
コード例 #24
0
ファイル: encoder.go プロジェクト: erkl/binn
func (pe *pointerEncoder) encode(b []byte, v reflect.Value) []byte {
	if v.IsNil() {
		return append(b, 0x10)
	} else {
		return pe.encodeElem(b, v.Elem())
	}
}
コード例 #25
0
ファイル: bson_decode.go プロジェクト: teopeurt/go-mongo
func decodeMap(d *decodeState, kind int, v reflect.Value) {
	t := v.Type()
	if t.Key().Kind() != reflect.String || kind != kindDocument {
		d.saveErrorAndSkip(kind, t)
		return
	}
	if v.IsNil() {
		v.Set(reflect.MakeMap(t))
	}
	subv := reflect.New(t.Elem()).Elem()
	offset := d.beginDoc()
	for {
		kind, name := d.scanKindName()
		if kind == 0 {
			break
		}
		if kind == kindNull {
			continue
		}
		subv.Set(reflect.Zero(t.Elem()))
		d.decodeValue(kind, subv)
		v.SetMapIndex(reflect.ValueOf(string(name)), subv)
	}
	d.endDoc(offset)
}
コード例 #26
0
ファイル: decode_slice.go プロジェクト: h12w/msgpack
func decodeSliceValue(d *Decoder, v reflect.Value) error {
	n, err := d.DecodeArrayLen()
	if err != nil {
		return err
	}

	if n == -1 {
		v.Set(reflect.Zero(v.Type()))
		return nil
	}
	if n == 0 && v.IsNil() {
		v.Set(reflect.MakeSlice(v.Type(), 0, 0))
		return nil
	}

	if v.Cap() >= n {
		v.Set(v.Slice(0, n))
	} else if v.Len() < v.Cap() {
		v.Set(v.Slice(0, v.Cap()))
	}

	for i := 0; i < n; i++ {
		if i >= v.Len() {
			v.Set(growSliceValue(v, n))
		}
		sv := v.Index(i)
		if err := d.DecodeValue(sv); err != nil {
			return err
		}
	}

	return nil
}
コード例 #27
0
// Validates that if a value is provided for a field, that value must be at
// least a minimum length.
func validateFieldMin(f reflect.StructField, fvalue reflect.Value) error {
	minStr := f.Tag.Get("min")
	if minStr == "" {
		return nil
	}
	min, _ := strconv.ParseInt(minStr, 10, 64)

	kind := fvalue.Kind()
	if kind == reflect.Ptr {
		if fvalue.IsNil() {
			return nil
		}
		fvalue = fvalue.Elem()
	}

	switch fvalue.Kind() {
	case reflect.String:
		if int64(fvalue.Len()) < min {
			return fmt.Errorf("field too short, minimum length %d", min)
		}
	case reflect.Slice, reflect.Map:
		if fvalue.IsNil() {
			return nil
		}
		if int64(fvalue.Len()) < min {
			return fmt.Errorf("field too short, minimum length %d", min)
		}

		// TODO min can also apply to number minimum value.

	}
	return nil
}
コード例 #28
0
ファイル: print.go プロジェクト: jianfengye/godetail
// NotNilFilter returns true for field values that are not nil;
// it returns false otherwise.
func NotNilFilter(_ string, v reflect.Value) bool {
	switch v.Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return !v.IsNil()
	}
	return true
}
コード例 #29
0
ファイル: yaml.go プロジェクト: samsalisbury/yaml
func isZero(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.String:
		return len(v.String()) == 0
	case reflect.Interface, reflect.Ptr:
		return v.IsNil()
	case reflect.Slice:
		return v.Len() == 0
	case reflect.Map:
		return v.Len() == 0
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Struct:
		vt := v.Type()
		for i := v.NumField() - 1; i >= 0; i-- {
			if vt.Field(i).PkgPath != "" {
				continue // Private field
			}
			if !isZero(v.Field(i)) {
				return false
			}
		}
		return true
	}
	return false
}
コード例 #30
0
ファイル: reflects_test.go プロジェクト: hiromaily/golibs
func display(name string, v reflect.Value) {
	switch v.Kind() { //uint
	case reflect.Invalid:
		fmt.Printf("%s = invalid\n", name)
	case reflect.Slice, reflect.Array:
		for i := 0; i < v.Len(); i++ {
			display(fmt.Sprintf("%s[%d]", name, i), v.Index(i))
		}
	case reflect.Struct:
		for i := 0; i < v.NumField(); i++ {
			fieldPath := fmt.Sprintf("%s.%s", name, v.Type().Field(i).Name)
			display(fieldPath, v.Field(i))
		}
	case reflect.Map:
		for _, key := range v.MapKeys() {
			display(fmt.Sprintf("%s[%s]", name,
				formatAtom(key)), v.MapIndex(key))
		}
	case reflect.Ptr:
		if v.IsNil() {
			fmt.Printf("%s = nil\n", name)
		} else {
			display(fmt.Sprintf("(*%s)", name), v.Elem())
		}
	case reflect.Interface:
		if v.IsNil() {
			fmt.Printf("%s = nil\n", name)
		} else {
			fmt.Printf("%s.type = %s\n", name, v.Elem().Type())
			display(name+".value", v.Elem())
		}
	default: // basic types, channels, funcs
		fmt.Printf("%s = %s\n", name, formatAtom(v))
	}
}