2016-10-02 58 views
0

我想了解在我的公司使用的代碼。我是朗新郎,我已經在他們的官方網站上看過這個教程。但是,我很難在空接口(即接口{})中包裝頭部。從各種網絡資源中,我發現空的接口可以容納任何類型的接口。但是,我很難搞清楚代碼庫,特別是一些功能。我不會在這裏發佈整個東西,而只是它使用的最小功能。請多多包涵!在去使用空接口

Function (I am trying to understand): 

func (this *RequestHandler) CreateAppHandler(rw http.ResponseWriter, r *http.Request) *foo.ResponseError { 
    var data *views.Data = &views.Data{Attributes: &domain.Application{}} 
    var request *views.Request = &views.Request{Data: data} 


    if err := json.NewDecoder(r.Body).Decode(request); err != nil { 
     logrus.Error(err) 
     return foo.NewResponsePropogateError(foo.STATUS_400, err) 
    } 
    requestApp := request.Data.Attributes.(*domain.Application) 
    requestApp.CreatedBy = user 

設置一些上下文中,RequestHandler是在相同的封裝中此代碼所限定的結構。 domainviews是單獨的包。應用程序是包域中的結構。下面兩個結構是封裝視圖部分:

type Data struct { 
    Id   string  `json:"id"` 
    Type  string  `json:"type"` 
    Attributes interface{} `json:"attributes"` 
} 

type Request struct { 
    Data *Data `json:"data"` 
} 

以下是包JSON的一部分:

func NewDecoder(r io.Reader) *Decoder { 
    return &Decoder{r: r} 
} 

func (dec *Decoder) Decode(v interface{}) error { 
    if dec.err != nil { 
     return dec.err 
    } 

    if err := dec.tokenPrepareForDecode(); err != nil { 
     return err 
    } 

    if !dec.tokenValueAllowed() { 
     return &SyntaxError{msg: "not at beginning of value"} 
    } 

    // Read whole value into buffer. 
    n, err := dec.readValue() 
    if err != nil { 
     return err 
    } 
    dec.d.init(dec.buf[dec.scanp : dec.scanp+n]) 
    dec.scanp += n 

    // Don't save err from unmarshal into dec.err: 
    // the connection is still usable since we read a complete JSON 
    // object from it before the error happened. 
    err = dec.d.unmarshal(v) 

    // fixup token streaming state 
    dec.tokenValueEnd() 

    return err 
} 


type Decoder struct { 
    r  io.Reader 
    buf []byte 
    d  decodeState 
    scanp int // start of unread data in buf 
    scan scanner 
    err error 

    tokenState int 
    tokenStack []int 
} 

現在,我理解的是,在包裝的觀點的結構數據,應用程序是被設置爲空接口的類型。之後,創建指向可變數據的指向同一包中的請求的指針。

我有以下幾點疑惑:

  1. 究竟this關鍵字在圍棋是什麼意思?寫作this * RequestHandler的目的是什麼?
  2. Go中的結構初始化可以通過指定其所有成員的值將其分配給變量來完成。但是,在這裏,對於結構Data,只分配了空接口值,而其他兩個字段的值未分配?
  3. 將Application結構分配給空接口的優點是什麼?這是否意味着我可以直接使用接口變量使用結構成員?
  4. 有人可以幫我弄清這個聲明的含義嗎? json.NewDecoder(r.Body).Decode(request)

雖然我知道這太多了,但我很難弄清楚Go中接口的含義。請幫忙!

回答

1
  1. this在go中不是關鍵字;任何變量名都可以在那裏使用。這就是所謂的接收器。以這種方式聲明的函數必須被調用,如thing.func(params),其中「thing」是接收者類型的表達式。在該功能中,接收器被設置爲值thing

  2. 結構文字不必包含所有字段(或其中任何字段)的值。未明確設置的任何字段的零值都會爲其類型的

  3. 正如你所說,一個空的接口可以採取任何類型的值。要使用interface{}類型的值,你可以使用類型斷言式開關確定值的類型,或者你可以使用反射使用的值,而無需有代碼的特定類型。

  4. 關於該陳述的具體內容你不明白嗎? json是聲明函數NewDecoder的包的名稱。該函數被調用,然後在該返回值上調用Decode函數(該函數由返回值類型NewDecoder實現)。

你可能想看看Effective Go和/或The Go Programming Language Specification以獲取更多信息。