为什么http.Client {}以&为前缀? [英] Why is http.Client{} prefixed with &?

查看:77
本文介绍了为什么http.Client {}以&为前缀?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Go,正在阅读有关> net/http 的Go官方文档,并且我从doc编写了以下代码进行测试:

I am learning Go and I am reading Go's official documentation about net/http, and I write following code from doc for test:

package main

import (
    "net/http"
    "fmt"
)

func main() {
    client := &http.Client{}
    resp, _ := client.Get("http://example.com")

    fmt.Println(resp)
}

http.Client是一个结构,但是我不知道为什么要加前缀&指针.我认为没有必要创建http.Client引用.为什么client变量具有Get方法?我正在阅读net/http的源代码,它在下面定义了Client结构:

http.Client is a struct, but I do not know why there is a & pointer prefixed. I think creating a http.Client reference is not necessary. And why does the client variable have a Get method? I am reading the source code of net/http, it defines the Client struct below:

type Client struct {
    Transport RoundTripper
    CheckRedirect func(req *Request, via []*Request) error
    Jar CookieJar
    Timeout time.Duration
}

Client结构没有定义Get方法;为什么client变量具有Get方法?

The Client struct does not have a Get method defined; why does the client variable have a Get method?

推荐答案

我真的会选择开始旅行首先了解该语言及其基本语法.

I would really take the Go Tour to get a feeling of the language and its basic syntax first.

您引用的类型声明仅包含结构的字段,但不包含其方法.方法是在其他地方定义的,例如函数,但是添加了 receiver 来指定方法所属的类型.例如,Client.Get()方法的定义是这样的:

The type declaration you quoted only contains the fields of the struct, but not its methods. Methods are defined elsewhere, like functions but with a receiver added which designates the type they belong to. For example the definition of Client.Get() method is this:

func (c *Client) Get(url string) (resp *Response, err error) {
    req, err := NewRequest("GET", url, nil)
    if err != nil {
        return nil, err
    }
    return c.Do(req)
}

方法名称前的部分称为接收器,它指定方法所要登录的类型(在此示例中为*Client).有关更多详细信息,请参见规范:方法声明.

The part before the method name is called the receiver, and that designates the type the method belogns to (*Client in this example). See Spec: Method declarations for more details.

&地址运算符,它采用其操作数的地址.在这种情况下,本地变量client的类型为 *http.Client . http.Client{}复合文字,它创建结构类型为http.Client的值,而&接受存储该结构值的匿名变量的地址:

The & is an address operator, it takes the address of its operand. In this case the local variable client will be of type *http.Client. http.Client{} is a composite literal which creates a value of the struct type http.Client, and & takes the address of the anonymous variable where this struct value is stored:

获取复合文字的地址会生成指向唯一

Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.

使用它是为了使client变量成为指向http.Client值的指针,鼓励将其共享和重用:

It is used so that the client variable will be a pointer to an http.Client value, one that is encouraged to be shared and reused:

客户端的传输通常具有内部状态(缓存的TCP连接),因此应重新使用客户端,而不是根据需要创建客户端.客户端可以安全地被多个goroutine并发使用.

The Client's Transport typically has internal state (cached TCP connections), so Clients should be reused instead of created as needed. Clients are safe for concurrent use by multiple goroutines.

如果client是指针,则可以将其自由传递给其他函数,仅复制指针值,而不复制指向的http.Client结构,因此结构本身(http.Client值)将被重用.如果不使用指针,则将其传递给其他函数时,该结构本身将被复制且不会重用.

And if client is a pointer, you are free to pass it around to other functions, only the pointer value will be copied, not the pointed http.Client struct, so the struct itself (the http.Client value) will be reused. Should you not use a pointer, if you would pass it to other functions, the struct itself would be copied and not reused.

请注意,在这个简单的示例中,这并不重要,因为即使http.Client的所有方法都是使用指针接收器声明的,您仍然可以在非指针变量上调用指针方法,因为client.Get()将是一个(&client).Get()的简写. 规范:调用:

Note that in this simple example it doesn't really matter, as even though all methods of http.Client are declared with pointer receiver, you can still call pointer methods on non-pointer variables, as client.Get() would be a shorthand for (&client).Get(). This is mentioned in Spec: Calls:

如果x可寻址,并且&x的方法集包含mx.m()(&x).m()的简写.

If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().

因此,即使在此简单示例中无需使用&地址运算符,也应保持使用它的习惯,无论示例是否扩展,或者您应该在这很重要的地方编写代码(例如,将创建的内容传递给其他人)客户).

So even though the & address operator is not needed in this simple example, it's good to keep the habit of using it, should the example grow or should you write code where this does matter (e.g. you pass around the created client).

这篇关于为什么http.Client {}以&为前缀?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆