// setInterfaceValue sets an interface value to a concrete value through // reflection. If the concrete value does not implement the interface, the // setting will panic. This routine turns the panic into an error return. // This dance avoids manually checking that the value satisfies the // interface. // TODO(rsc): avoid panic+recover after fixing issue 327. func setInterfaceValue(ivalue *reflect.InterfaceValue, value reflect.Value) { defer func() { if e := recover(); e != nil { error(e.(os.Error)) } }() ivalue.Set(value) }
// encodeInterface encodes the interface value iv. // To send an interface, we send a string identifying the concrete type, followed // by the type identifier (which might require defining that type right now), followed // by the concrete value. A nil value gets sent as the empty string for the name, // followed by no value. func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv *reflect.InterfaceValue) { state := enc.newEncoderState(b) state.fieldnum = -1 state.sendZero = true if iv.IsNil() { state.encodeUint(0) return } ut := userType(iv.Elem().Type()) name, ok := concreteTypeToName[ut.base] if !ok { errorf("gob: type not registered for interface: %s", ut.base) } // Send the name. state.encodeUint(uint64(len(name))) _, err := state.b.WriteString(name) if err != nil { error(err) } // Define the type id if necessary. enc.sendTypeDescriptor(enc.writer(), state, ut) // Send the type id. enc.sendTypeId(state, ut) // Encode the value into a new buffer. Any nested type definitions // should be written to b, before the encoded value. enc.pushWriter(b) data := new(bytes.Buffer) enc.encode(data, iv.Elem(), ut) if enc.err != nil { error(enc.err) } enc.popWriter() enc.writeMessage(b, data) if enc.err != nil { error(err) } enc.freeEncoderState(state) }