理解这段代码(Go语言),双括号 ()()

huangapple go评论75阅读模式
英文:

Understand this code (golang), double parantheses ()()

问题

我想知道是否有人可以解释一下这个语法给我。在Google Maps Go API中,他们有以下代码:

type Client struct {
	httpClient        *http.Client
	apiKey            string
	baseURL           string
	clientID          string
	signature         []byte
	requestsPerSecond int
	rateLimiter       chan int
}

// NewClient constructs a new Client which can make requests to the Google Maps WebService APIs.
func NewClient(options ...ClientOption) (*Client, error) {
	c := &Client{requestsPerSecond: defaultRequestsPerSecond}
	WithHTTPClient(&http.Client{})(c)		//???????????
	for _, option := range options {
		err := option(c)
		if err != nil {
			return nil, err
		}
	}
	if c.apiKey == "" && (c.clientID == "" || len(c.signature) == 0) {
		return nil, errors.New("maps: API Key or Maps for Work credentials missing")
	}

	// Implement a bursty rate limiter.
	// Allow up to 1 second worth of requests to be made at once.
	c.rateLimiter = make(chan int, c.requestsPerSecond)
	// Prefill rateLimiter with 1 seconds worth of requests.
	for i := 0; i < c.requestsPerSecond; i++ {
		c.rateLimiter <- 1
	}
	go func() {
		// Wait a second for pre-filled quota to drain
		time.Sleep(time.Second)
		// Then, refill rateLimiter continuously
		for _ = range time.Tick(time.Second / time.Duration(c.requestsPerSecond)) {
			c.rateLimiter <- 1
		}
	}()

	return c, nil
}

// WithHTTPClient configures a Maps API client with a http.Client to make requests over.
func WithHTTPClient(c *http.Client) ClientOption {
	return func(client *Client) error {
		if _, ok := c.Transport.(*transport); !ok {
			t := c.Transport
			if t != nil {
				c.Transport = &transport{Base: t}
			} else {
				c.Transport = &transport{Base: http.DefaultTransport}
			}
		}
		client.httpClient = c
		return nil
	}
}

这是我不理解的一行代码:

WithHTTPClient(&http.Client{})(c)

为什么有两个()?
我看到WithHTTPClient接受一个*http.Client,而这一行代码中传递了一个指向上面声明的client结构体的指针?

英文:

I was wondering if someone can explain this syntax to me. In the google maps go api, they have

type Client struct {
	httpClient        *http.Client
	apiKey            string
	baseURL           string
	clientID          string
	signature         []byte
	requestsPerSecond int
	rateLimiter       chan int
}

// NewClient constructs a new Client which can make requests to the Google Maps WebService APIs.
func NewClient(options ...ClientOption) (*Client, error) {
	c := &amp;Client{requestsPerSecond: defaultRequestsPerSecond}
	WithHTTPClient(&amp;http.Client{})(c)		//???????????
	for _, option := range options {
		err := option(c)
		if err != nil {
			return nil, err
		}
	}
	if c.apiKey == &quot;&quot; &amp;&amp; (c.clientID == &quot;&quot; || len(c.signature) == 0) {
		return nil, errors.New(&quot;maps: API Key or Maps for Work credentials missing&quot;)
	}

	// Implement a bursty rate limiter.
	// Allow up to 1 second worth of requests to be made at once.
	c.rateLimiter = make(chan int, c.requestsPerSecond)
	// Prefill rateLimiter with 1 seconds worth of requests.
	for i := 0; i &lt; c.requestsPerSecond; i++ {
		c.rateLimiter &lt;- 1
	}
	go func() {
		// Wait a second for pre-filled quota to drain
		time.Sleep(time.Second)
		// Then, refill rateLimiter continuously
		for _ = range time.Tick(time.Second / time.Duration(c.requestsPerSecond)) {
			c.rateLimiter &lt;- 1
		}
	}()

	return c, nil
}

// WithHTTPClient configures a Maps API client with a http.Client to make requests over.
func WithHTTPClient(c *http.Client) ClientOption {
	return func(client *Client) error {
		if _, ok := c.Transport.(*transport); !ok {
			t := c.Transport
			if t != nil {
				c.Transport = &amp;transport{Base: t}
			} else {
				c.Transport = &amp;transport{Base: http.DefaultTransport}
			}
		}
		client.httpClient = c
		return nil
	}
}

And this is the line I don't understand in NewClient

WithHTTPClient(&amp;http.Client{})(c)

Why are there two ()()?
I see that WithHTTPClient takes in a *http.Client which that line does, but then it also passes in a pointer to the client struct declared above it?

答案1

得分: 6

WithHTTPClient 返回一个函数,例如:

func WithHTTPClient(c *http.Client) ClientOption {
    return func(client *Client) error {
        ....
        return nil
    }
}

WithHTTPClient(&amp;http.Client{})(c) 只是将 c(一个指向 Client 的指针)作为参数调用该函数。可以将其写成:

f := WithHTTPClient(&amp;http.Client{})
f(c)
英文:

WithHTTPClient returns a function, ie:

func WithHTTPClient(c *http.Client) ClientOption {
    return func(client *Client) error {
        ....
        return nil
    }
}

WithHTTPClient(&amp;http.Client{})(c) is just calling that function with c (a pointer to a Client) as parameter. It could be written as:

f := WithHTTPClient(&amp;http.Client{})
f(c)

huangapple
  • 本文由 发表于 2017年1月19日 02:58:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/41727326.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定