我正在学习Go,我正在阅读Go关于net/http的官方文档,并编写了下面的文档代码供测试:
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结构:
type Client struct {
Transport RoundTripper
CheckRedirect func(req *Request, via []*Request) error
Jar CookieJar
Timeout time.Duration
}Client结构没有定义Get方法;为什么client变量有Get方法?
发布于 2017-08-18 08:16:42
首先,我会使用游玩来了解该语言及其基本语法。
您引用的类型声明仅包含结构的字段,而不包含其方法。方法是在其他地方定义的,比如函数,但是添加了一个接收器来指定它们所属的类型。例如,Client.Get()方法的定义如下:
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)
}方法名称之前的部分称为接收方,它指定方法belogns到的类型(本例中为*Client)。有关更多详细信息,请参阅规范:方法声明。
&是一个地址运算符,它接受其操作数的地址。在这种情况下,局部变量client将是*http.Client类型。http.Client{}是一个复合文字,它创建一个结构类型http.Client的值,&接受存储此结构值的匿名变量的地址:
使用它时,client变量将是指向http.Client值的指针,该值鼓励共享和重用:
客户端的传输通常具有内部状态(缓存的TCP连接),因此应该重用客户机,而不是根据需要创建客户端。客户端可以安全地同时供多个用户使用。
如果client是一个指针,您可以自由地将它传递给其他函数,只有指针值将被复制,而不是指向的http.Client结构,因此结构本身( http.Client值)将被重用。如果不使用指针,如果要将指针传递给其他函数,则结构本身将被复制,而不是重用。
注意,在这个简单的例子中,这并不重要,因为即使所有的http.Client方法都是用指针接收器声明的,您仍然可以对非指针变量调用指针方法,因为client.Get()将是(&client).Get()的缩写。在规范:呼叫:中提到了这一点
如果
x是可寻址,&x的方法集包含m,那么x.m()是(&x).m()的缩写。
因此,即使在这个简单的示例中不需要&地址操作符,如果这个示例增长了,或者您应该编写代码(例如,在创建的客户机中传递),保持使用它的习惯是很好的。
https://stackoverflow.com/questions/45751608
复制相似问题