func SetValue()

in codec.go [275:341]


func SetValue(dest, v reflect.Value) {
	// zero value not need to set
	if !v.IsValid() {
		return
	}

	vType := v.Type()
	destType := dest.Type()

	// for most cases, the types are the same and can set the value directly.
	if dest.CanSet() && destType == vType {
		dest.Set(v)
		return
	}

	// check whether the v is a ref holder
	if vType == _refHolderPtrType {
		h := v.Interface().(*_refHolder)
		h.add(dest)
		return
	}

	vRawType, vPtrDepth := UnpackType(vType)

	// unpack to the root addressable value, so that to set the value.
	dest = UnpackToRootAddressableValue(dest)
	destType = dest.Type()
	destRawType, destPtrDepth := UnpackType(destType)

	// it can set the value directly if the raw types are of the same type.
	if destRawType == vRawType {
		if destPtrDepth > vPtrDepth {
			// pack to the same level of dest
			for i := 0; i < destPtrDepth-vPtrDepth; i++ {
				v = PackPtr(v)
			}
		} else if destPtrDepth < vPtrDepth {
			// unpack to the same level of dest
			for i := 0; i < vPtrDepth-destPtrDepth; i++ {
				v = v.Elem()
			}
		}

		dest.Set(v)

		return
	}

	switch destType.Kind() {
	case reflect.Float32, reflect.Float64:
		dest.SetFloat(v.Float())
		return
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		dest.SetInt(v.Int())
		return
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		// hessian only support 64-bit signed long integer.
		dest.SetUint(uint64(v.Int()))
		return
	case reflect.Ptr:
		SetValueToPtrDest(dest, v)
		return
	default:
		// It's ok when the dest is an interface{}, while the v is a pointer.
		dest.Set(v)
	}
}