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
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
}
The Client
struct does not have a Get
method defined; why does the client
variable have a Get
method?
Go is a language designed by Google for use in a modern internet environment. It comes with a highly capable standard library and a built-in HTTP client.
It establishes network connections as needed 40 // and caches them for reuse by subsequent calls. It uses HTTP proxies 41 // as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and 42 // $no_proxy) environment variables.
I would really take the Go Tour to get a feeling of the language and its basic syntax first.
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)
}
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.
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.
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:
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.
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.
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:
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With