Golang Martini Source Reading notes inject

Source: Internet
Author: User

Martini is a super lightweight web-open-source framework written in go language that can be found in GitHub search. 13 that would start to touch the go language with a slight look at the framework, because it was not continued to use go to slowly ignore, and recently because the project at hand may be used, and therefore think of this framework.

The update on GitHub shows that the project is a good framework, and simple and efficient things have never lacked a champion. Weekend reading Martini Source made comments write down some understanding, mainly Inject.go and martini.go two files, subsequent estimates will read the main file of the routing function.

Note: The following ' generics ' all represent interface{} types

Inject.go

Package Injectimport ("FMT" "reflect")//Implement callback function parameter value injection, concept viewing Mencius Martini Framework, Injector is used to store middleware functions and user-defined function callback parameters type Injector I Nterface {applicator//struct individual field assignment Invoker//interface Typemapper//Type mapping interface for function invocation through reflection, Typemapper function is related to the system design intention, M Apper according to the type key value key, the same type has only one value corresponding to SetParent (Injector)}//for each field of the struct type is dynamically assigned type applicator interface {//for struct definition, with ' Inject ' label fields are assigned Apply (interface{}) error}//implement function calls by reflection type Invoker Interface {//parameter type is a function type, use reflection to get function parameter type, according to each parameter class Type to get the corresponding value and call the function invoke (interface{}) ([]reflect.  Value, error)}//the value of the parameter to the type of the mapping interface types Typemapper Interface {///specific type mappings, direct mapping based on the specific type of the value map (interface{}) Typemapper// The mapping between ' generics ' and specific types, the second parameter must be a generic pointer type//Because only the generic type is needed here, only the generic pointer cost is minimal, because it only needs to use its type part//here to understand the specific implementation of interface{} Mapto (in terface{}, interface{}) Typemapper Set (reflect. Type, reflect. Value) Typemapper Get (reflect. Type) reflect. Value//Find values by type}//here is similar to dividing all golang types into two large types: generic interface{} with specific type concrete Typetype injector struct {ValuEs map[reflect. Type]reflect. Value//stores the values of the struct field in the above procedure, and the value of the function invocation parameter parent Injector//}//queries the interface type of value, applies to interface{} type mappings, if value is not a pointer type will return an exception//this The interface is only used in generic mappings, so only the type portion of Func interfaceof (value interface{}) is obtained from value (interface{}) reflect. Type {t: = reflect. TypeOf (value)//Gets the value of type for t.kind () = = reflect. PTR {//If it is a pointer, continue to check the pointer to T = T.elem ()//pointer to the element} if T.kind ()! = reflect. Interface {//finally must point to Interface, if not, the parameter passed in has a problem panic ("called Inject. Interfaceof with a value, which is a pointer to an interface. (*myinterface) (nil)} return t}//new returns a new injector.//create an injection tool that provides data storage and querying, and other functions primarily depend on the implementation of the Reflection Library Func New () Injector {Retu RN &injector{Values:make (map[reflect. Type]reflect. Value), the}}//parameter type is function func, which uses the reflection interface to complete the function call Func (inj *injector) Invoke (F interface{}) ([]reflect. Value, error) {t: = reflect. TypeOf (f)//Gets the type part of F, here is the function type var in = make ([]reflect. Value, T.numin ())//panic if T is not kind of Func//create storage parameter space 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, from here also can see the same type, only one value if!val. IsValid () {return nil, fmt.  Errorf ("Value not found for type%v", Argtype)} In[i] = val}//Reflection type of function call, take out the data portion of F, that is, the instance value function return Reflect. ValueOf (f). Called (in), the nil//function call}//the concrete implementation of the struct assignment func (inj *injector) Apply (Val interface{}) Error {V: = reflect. ValueOf (val) for v.kind () = = reflect. Ptr {v = V.elem ()} if V.kind ()! = reflect.    Struct {return nil//should not panic here? } t: = V.type ()//Gets the type of struct for I: = 0; I < V.numfield (); i++ {//Gets the number of fields F: = V.field (i) Structfield: = T.field (i)///with ' inject ' label may be assigned if F.canset (  ) && (Structfield.tag = = "inject" | | structField.Tag.Get ("inject")! = "") {ft: = F.type () v : = INJ. Get (ft) if!v.isvalid () {return FMT.  Errorf ("Value not found for type%v", ft)          } f.set (v)}} return nil}//specific type parameter, type-to-value mapping func (i *injector) map (Val interface{}) Typem Apper {//Type and value mapping I.values[reflect. TypeOf (val)] = reflect. ValueOf (val) return i}//generic type mapping func (i *injector) Mapto (Val interface{}, Ifaceptr interface{}) typemapper {//need to get first The generic pointer points to the specific generic type i.values[interfaceof (ifaceptr)] = reflect. ValueOf (val) return I}func (i *injector) Set (Typ reflect. Type, Val reflect. Value) Typemapper {I.values[typ] = val return i}//based on the type lookup value func (i *injector) Get (t reflect. Type) reflect. Value {val: = i.values[t]//First make a simple type of query if Val. IsValid () {return Val}//No concrete types found, try to find implementors//If T was an interface I F t.kind () = = reflect. Interface {//T is Interface type for k, V: = range I.values {//Iteration query if K.implements (t) {//For each type To see if the T interface is implemented Val = v Break}}}//Cannot find, go to Father node Find//Still no type found, try-to-look it-on the parent if!val. IsValid () && i.parent! = Nil {val = I.parent.get (t)} return Val}func (i *injector) SetParent (paren T Injector) {i.parent = parent}

If the understanding has errors, welcome in the comments pointed out, greatly appreciated!

Golang Martini Source Reading notes inject

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.