【问题标题】:Using empty interfaces in go在 go 中使用空接口
【发布时间】:2016-10-03 03:41:20
【问题描述】:

我正在尝试了解我公司使用的代码。我是新手,我已经浏览了他们官方网站上的教程。但是,我很难将头绕在空接口上,即 interface{}。从网上的各种来源,我发现空接口可以容纳任何类型。但是,我很难弄清楚代码库,尤其是其中的一些功能。我不会在这里发布整个内容,而只是在其中使用它的最小功能。请多多包涵!

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
}

现在,我了解到,在包视图中的 struct Data 中,Application 被设置为空接口的类型。之后,会创建一个指向同一包中的 Request 的指针,该指针指向变量 data。

我有以下疑惑:

  1. this 关键字在 Go 中到底是什么意思?写this * RequestHandler的目的是什么?
  2. Go 中结构的初始化可以在通过指定其所有成员的值将其分配给变量时完成。但是,这里对于structData,只赋值了空接口值,不赋值其他两个字段的值?
  3. 将 Application 结构分配给空接口有什么好处?这是否意味着我可以直接使用接口变量使用结构成员?
  4. 谁能帮我弄清楚这句话的意思? json.NewDecoder(r.Body).Decode(request)?

虽然我知道这太多了,但我很难弄清楚 Go 中接口的含义。请帮忙!

【问题讨论】:

    标签: go


    【解决方案1】:
    1. this 不是 go 中的关键字;任何变量名都可以在那里使用。这就是所谓的接收器。以这种方式声明的函数必须像thing.func(params) 一样调用,其中“thing”是接收者类型的表达式。在函数中,接收者被设置为thing的值。

    2. 结构字面量不必包含所有字段(或任何字段)的值。任何未明确设置的字段的类型都将具有零值

    3. 正如您所说,空接口可以采用任何类型的值。要使用 interface{} 类型的值,您可以使用 type assertiontype switch 来确定值的类型,或者您可以使用 reflection 来使用该值,而不必具有特定类型的代码。

    4. 您不理解该声明的具体哪些内容? json 是声明函数 NewDecoder 的包的名称。调用该函数,然后在该返回值上调用Decode 函数(由NewDecoder 的返回值类型实现)。

    您可能需要查看Effective Go 和/或The Go Programming Language Specification 了解更多信息。

    【讨论】:

      猜你喜欢
      • 2011-10-25
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 2018-04-16
      相关资源
      最近更新 更多