0

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 {
}
0

3 Answers 3

3

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 ...
}

Source code

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()
Sign up to request clarification or add additional context in comments.

Comments

1

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 !

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.