codec.go
func (cdc *Codec) RegisterInterface(ptr interface{}, iopts *InterfaceOptions) {
	cdc.assertNotSealed()

	// Get reflect.Type from ptr.
	rt := getTypeFromPointer(ptr)
	if rt.Kind() != reflect.Interface {
		panic(fmt.Sprintf("RegisterInterface expects an interface, got %v", rt))
	}

	// Construct InterfaceInfo
	var info = cdc.newTypeInfoFromInterfaceType(rt, iopts)

	// Finally, check conflicts and register.
	func() {
		cdc.mtx.Lock()
		defer cdc.mtx.Unlock()

		cdc.collectImplementers_nolock(info)
		err := cdc.checkConflictsInPrio_nolock(info)
		if err != nil {
			panic(err)
		}
		cdc.setTypeInfo_nolock(info)
	}()
	/*
		NOTE: The above func block is a defensive pattern.

		First of all, the defer call is necessary to recover from panics,
		otherwise the Codec would become unusable after a single panic.

		This “defer-panic-unlock” pattern requires a func block to denote the
		boundary outside of which the defer call is guaranteed to have been
		called.  In other words, using any other form of curly braces (e.g.  in
		the form of a conditional or looping block) won't actually unlock when
		it might appear to visually.  Consider:

		```
		var info = ...
		{
			cdc.mtx.Lock()
			defer cdc.mtx.Unlock()

			...
		}
		// Here, cdc.mtx.Unlock() hasn't been called yet.
		```

		So, while the above code could be simplified, it's there for defense.
	*/
}
func (cdc *Codec) RegisterInterface(ptr interface{}, iopts *InterfaceOptions) {
	cdc.assertNotSealed()

	// Get reflect.Type from ptr.
	rt := getTypeFromPointer(ptr)
	if rt.Kind() != reflect.Interface {
		panic(fmt.Sprintf("RegisterInterface expects an interface, got %v", rt))
	}

	// Construct InterfaceInfo
	var info = cdc.newTypeInfoFromInterfaceType(rt, iopts)

	// Finally, check conflicts and register.
	func() {
		cdc.mtx.Lock()
		defer cdc.mtx.Unlock()

		cdc.collectImplementers_nolock(info)
		err := cdc.checkConflictsInPrio_nolock(info)
		if err != nil {
			panic(err)
		}
		cdc.setTypeInfo_nolock(info)
	}()
	/*
		NOTE: The above func block is a defensive pattern.

		First of all, the defer call is necessary to recover from panics,
		otherwise the Codec would become unusable after a single panic.

		This “defer-panic-unlock” pattern requires a func block to denote the
		boundary outside of which the defer call is guaranteed to have been
		called.  In other words, using any other form of curly braces (e.g.  in
		the form of a conditional or looping block) won't actually unlock when
		it might appear to visually.  Consider:

		```
		var info = ...
		{
			cdc.mtx.Lock()
			defer cdc.mtx.Unlock()

			...
		}
		// Here, cdc.mtx.Unlock() hasn't been called yet.
		```

		So, while the above code could be simplified, it's there for defense.
	*/
}
// This function should be used to register all interfaces that will be
// encoded/decoded by go-amino.
// Usage:
// `amino.RegisterInterface((*MyInterface1)(nil), nil)`