2017-08-18 103 views
-1

我學習圍棋,我讀Go的官方文檔中關於net/http,和我寫的文檔下面的代碼測試:爲什麼http.Client {}以前綴?

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方法?我讀「網/ HTTP」的源代碼,它定義如下Client結構:

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

Client結構沒有定義Get方法,但爲什麼client變量有Get方法?

+0

爲什麼要投票這個問題,請給出一些理由,所以我會注意問。 – TangMonk

+0

因爲它在提出問題之前顯示零研究努力。這在[spec](https://golang.org/ref/spec#Address_operators)和[tour](https://tour.golang.org/moretypes/1)中有詳細介紹。 – Adrian

+1

但方法接收器沒有在遊覽中提及,這是與學習者誤解的另一種語言不同的概念。並且直接將值傳遞給函數參數只是一個沒有指定的拷貝而沒有在巡視中提到的指針(我從來沒有使用直接使用指針來執行http請求的語言,ruby,java,python,elixir ...)。閱讀規範是無聊的,並渴望學習一門新的語言。我不認爲一個新鮮的問題是沒有價值的,你可以看到最後一個答案也是錯誤的,這意味着有些人還不瞭解這種語言。 – TangMonk

回答

6

我真的會認爲Go Tour首先感受到語言及其基本語法。

您引用的類型聲明僅包含字段的結構,但不包含其方法。方法在其他地方被定義,如函數,但是增加了一個接收器,它指定了它們所屬的類型。例如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在這個例子中)。有關更多詳細信息,請參閱Spec: Method declarations

&address operator,它取其操作數的地址。在這種情況下,局部變量client將是*http.Client類型。 http.Client{}composite literal其產生結構類型http.Client的值,並&取其中該結構值被存儲在匿名的變量的地址:

複合字面的Taking the address生成指向與初始化的獨特variable字面值。

它被用來使得client變量將是一個指向http.Client值,一個是鼓勵共享和再使用:

客戶端的傳輸通常具有內部狀態(緩存TCP連接),所以客戶端應該被重用,而不是根據需要創建。客戶端可以安全地由多個goroutine併發使用。

如果client是一個指針,你可以自由地圍繞它傳遞給其他的功能,只有指針值會被複制,而不是尖銳http.Client結構,使結構本身(http.Client值)將被重用。如果你不使用指針,如果你將它傳遞給其他函數,結構本身將被複制並且不被重用。

注意,在這個簡單的例子,它其實並不重要,因爲即使的http.Client所有方法都用指針接收申報,仍然可以呼籲非指針變量的指針方法,如client.Get()將是(&client).Get()的簡寫。這在Spec: Calls:

提到如果xaddressable&x的方法集包含mx.m()(&x).m()簡寫。

因此,即使在這個簡單的例子是不需要的&地址運算符,這是很好的繼續使用它,應該在例如成長的習慣,或者你應該寫代碼身在何處,這樣做(例如,你繞過創建客戶端)。

+0

謝謝,你救了我 – TangMonk

相關問題