golang martini source of reading notes inject

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

Guess you like

Origin blog.csdn.net/weixin_34270606/article/details/94267295