go martini is written in a super lightweight open-source web framework, the specific source can be found at github search. There will be 13 years that came into contact with the language go a little seen this framework, since then did not continue to use go slowly ignored, the recent project at hand may be used, and therefore thought of this framework.
The project continues to update the display, indicating that the framework is really a good, simple and efficient stuff never been a lack advocates on github. Weekend to do when reading martini source code annotated write down some understanding, mainly inject.go and martini.go two files, it is estimated will follow the main document and re-read the routing function.
NOTE: The following 'generic' each represents a type interface {}
inject.go
Inject Package Import ( "FMT" "the reflect" ) // injection parameter values to achieve the callback function, martini Throughout frame, it is for storing the Injector middleware functions, and user-defined parameters callback type interface Injector { Applicator // structure body each field assignment Invoker // function call to achieve through reflection interfaces TypeMapper // type mapping interface, TypeMapper functions and systems designed to have a relationship now, mapper according to the type of key key, the same type only a value corresponding SetParent ( Injector) } // dynamically assigned to each field of the structure type type Applicator interface { // definition of the structure, fields with 'inject' tag assign the Apply (interface {}) error } // reflected by manner function call type interface Invoker { // type parameter as a function of the type using reflection parameter type acquiring function to acquire a corresponding value according to the type of each parameter, and call the function invoke (interface {}) ([ ] reflect.Value, error ) } // parameter value type mapping interface type interface the TypeMapper { // particular type of mapping, to establish a direct mapping according to the particular type of value the Map (interface {}) the TypeMapper // mapping between a 'generic' and the particular type of two parameters must be generic pointer type // here only as required to obtain the generic type, only the minimum cost of a generic pointer, since it is used only type section // it should be understood that the particular interface {} achieve MapTo ({} interface, interface {}) the TypeMapper the Set (reflect.Type, reflect.Value) the TypeMapper the Get (reflect.Type) reflect.Value find a value according to a type // } // here is similar to all of the sub-types golang of two major types: a generic interface {} particular type type concrete type struct {Injector values Map [reflect.Type] value of the field structure reflect.Value // during storage, and the value of the function call parameters parent // Injector } // value query interface type for interface {} type of mapping, if the value is not a pointer type exception would return // This interface is only used in a generic mapping, so only from value (interface {}) Get the type section FUNC InterfaceOf (interface {value}) {reflect.Type T: = reflect.TypeOf (value) // Get type value for t.Kind () == reflect.Ptr {// If a pointer, the pointer continues to check t = t.Elem () // pointer element } IF t.Kind ()! = reflect.Interface {// the last is certainly pointing interface, and if not, indicating a problem with the parameters passed in panic ( "Called inject.InterfaceOf with a value that iS not a pointer to aN interface. (* MyInterface) (nil)") } return T } . a new new // Returns New Injector // Create a injection tool, provides data storage and query, other functions mainly dependent on the reflection library implementation FUNC New () Injector { return {& Injector values: the make (Map [the reflect. type] reflect.Value), } } // parameter type as a function func, reflection interfaces with a call completion functions FUNC (* Injector INJ) the Invoke (interface {f}) ([] reflect.Value, error) { T: = reflect.TypeOf (f) f // Get the type of part, here the function type var in = make ([ ] reflect.Value, t.NumIn ()) // Panic if t is not kind of Func // create storage space parameter for I: = 0; I <t.NumIn (); I ++ { argtype: = t.In (I) Val: = inj.Get (argtype) // get the value of the parameter according to the parameter type, there can also be seen from the same type, only one value IF val.IsValid () {! return nil, fmt.Errorf ( "Not found for the value type V%", argtype) } in [I] = Val } // function call of a reflective type, the data extraction section f, i.e., the value of function examples return reflect.ValueOf (f) .Call (in ), nil // function calls } V: = reflect.ValueOf (Val) // embodied as a structure assignment FUNC (* Injector INJ) the Apply (Val interface {}) {error return fmt.Errorf ("Value not found for type %v", ft) v.Kind for () == reflect.Ptr { v = v.Elem () } ! IF v.Kind () = reflect.Struct { return nil // Should not panic here Wallpaper? } t: = v.Type () // Get the type of structure for i: = 0; i < v.NumField (); i ++ {// Get the number of fields F: = v.Field (I) structField: = t.Field (I) // with there 'inject' tag can be assigned before IF f.CanSet () && {(structField.Tag == "Inject" || structField.Tag.Get ( "Inject") = ""!) . ft: = f.Type () V: = inj.Get (. ft) ! IF v.IsValid () { } f.Set (V) } } return nil } // particular type parameters, and the value map type FUNC (I * Injector) the Map (Val interface {}) the TypeMapper { // mapping type and value i.values [reflect.TypeOf (val)] = reflect.ValueOf (val ) return I } // generic type of mapping FUNC (I * Injector) MapTo (Val interface {}, {} ifacePtr interface) the TypeMapper { // need to obtain specific generic type generic pointer i.values [InterfaceOf (ifacePtr)] = reflect.ValueOf (Val) return I } FUNC (I * Injector) the Set (Typ reflect.Type, Val reflect.Value) the TypeMapper { i.values [Typ] = Val return I } // find the type value FUNC (I * Injector) the Get (T reflect.Type) {reflect.Value val: = i.values [t] // simple type of query to if val.IsValid () { Val return } // Concrete types found NO, the try to Find Implementors // T IS AN interface IF IF t.Kind () {// == reflect.Interface type of interface T for k, v: = range i.values { // iterative queries if k.Implements (t) {// for each type to see if it implements the interface t Val v = BREAK } } } // can not find, and went looking for his father node // Still no type found, IT ON look up to the try The parent IF! val.IsValid () && i.parent! {nil = Val = i.parent.Get (T) } return Val } FUNC (I * Injector) the SetParent (parent Injector) { i.parent = parent }
As understood there is an error, welcome in the comments pointed out, be grateful!
Reproduced in: https: //www.cnblogs.com/bicowang/p/5250590.html