为什么http.Client {}以&为前缀? [英] Why is http.Client{} prefixed with &?
问题描述
我正在学习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
的方法集包含m
,x.m()
是(&x).m()
的简写.
If
x
is addressable and&x
's method set containsm
,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屋!