在Go中使用空接口

3
我在尝试理解我公司使用的代码。我对Go语言还很陌生,已经完成了官方网站上的教程。然而,空接口(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则是不同的包。在domain包中,有一个名为Application的结构体。接下来要介绍的两个结构体则属于views包:

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

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

以下是 package.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
}

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

我有以下几个疑问:

  1. this关键字在Go中是什么意思?写this * RequestHandler有什么目的?
  2. 在Go中,可以通过指定所有成员的值将结构体初始化并赋值给变量。然而,在这里,对于结构体Data,只分配了空接口值,并没有分配其他两个字段的值?
  3. 将Application结构体分配给空接口的优点是什么?这是否意味着我可以直接使用接口变量来使用结构体成员?
  4. 有人可以帮我弄清楚这句话的含义吗?json.NewDecoder(r.Body).Decode(request)

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

1个回答

1
  1. this 不是 Go 语言的关键字,任何变量名都可以用在这里。那被称为 接收器。以这种方式声明的函数必须像 thing.func(params) 这样调用,其中 "thing" 是接收器类型的表达式。在函数内部,接收器被设置为 thing 的值。

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

  3. 如你所说,空接口可以取任何类型的值。要使用类型为 interface{} 的值,您可以使用 类型断言类型开关 来确定该值的类型,或者您可以使用 反射 来使用该值,而无需针对特定类型编写代码。

  4. 关于该语句的具体内容,您不理解的是什么?json 是一个包的名称,其中声明了函数 NewDecoder。调用该函数,然后在该返回值的类型实现的 Decode 函数上调用。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接