Reputation: 6733
Let's say I have this function
func main() {
x := 10
change(&x)
}
func change(n *int) {
}
If I don't use in n *int
the signature, the above function gives an error -
*cannot use &x (type int) as type int in argument to change
But why does the below example run fine without requiring a client *HTTPClient in the argument of send method though I'm passing a pointer in this case?
import (
"net/http"
)
// HTTPClient interface for making http requests
type HTTPClient interface {
Get(url string) (*http.Response, error)
}
func main() {
client := &http.Client{}
err := send(client, url)
}
func send(client HTTPClient, url string) error {
}
Upvotes: 0
Views: 282
Reputation: 12685
You are implementing a HTTPClient
interface which takes a function Get
. In go lang spec it is defined as
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)
}
In above function *Client
is a pointer receiver to method GET
. Client is a struct declared in Go source. For more information on http.Client
struct defined in net/http
package Check out Golang Spec.
In your first example code you are passing a pointer to Change
function.
package main
import (
"fmt"
)
type A interface{
Change(n *int)
}
func main() {
x := 10
Change(&x)
}
func Change(n *int) {
fmt.Println(*n+1)
}
Check working example on Go playground
Upvotes: 1
Reputation: 5898
HTTPClient
is an interface, it defines a single method Get(...)
The client struct, from http.Client
also has a get method, docs here.
func (c *Client) Get(url string) (resp *Response, err error) {
// trimmed ...
}
You can see from the definition above that Get(url)
has a "pointer receiver". This means that *http.Client
defines the Get(url)
method and not http.Client
. This means that *httpClient
implements the HTTPClient
interface and not http.Client
.
The last thing worth pointing out is that the go runtime will automatically dereference pointers if, the an interface is implemented by a "value receiver" and not a "pointer receiver".
An example of this could be:
type Valuer interface {
Value() string
}
type V struct {}
type (valueReceiver V) Value() string {
// trimmed ...
}
// Here given a *V not V, go will dereference *V to call the Value() method on V not *V
vPtr := &V{}
vPtr.Value()
Upvotes: 3
Reputation: 1782
http.Client
has a Get method with a pointer receiver (https://golang.org/pkg/net/http/#Client.Get), having the same signature as required by your HTTPCLient
interface, so it works !
Upvotes: 1