首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么http.Client{}前缀为&?

为什么http.Client{}前缀为&?
EN

Stack Overflow用户
提问于 2017-08-18 08:06:05
回答 1查看 3.3K关注 0票数 9

我正在学习Go,我正在阅读Go关于net/http的官方文档,并编写了下面的文档代码供测试:

代码语言:javascript
复制
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结构:

代码语言:javascript
复制
type Client struct {
    Transport RoundTripper
    CheckRedirect func(req *Request, via []*Request) error
    Jar CookieJar
    Timeout time.Duration
}

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-18 08:16:42

首先,我会使用游玩来了解该语言及其基本语法。

您引用的类型声明仅包含结构的字段,而不包含其方法。方法是在其他地方定义的,比如函数,但是添加了一个接收器来指定它们所属的类型。例如,Client.Get()方法的定义如下:

代码语言:javascript
复制
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()的缩写。

因此,即使在这个简单的示例中不需要&地址操作符,如果这个示例增长了,或者您应该编写代码(例如,在创建的客户机中传递),保持使用它的习惯是很好的。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45751608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档