gpt4 book ai didi

go - 重用结构以减少堆使用

转载 作者:数据小太阳 更新时间:2023-10-29 03:40:18 25 4
gpt4 key购买 nike

请解释以下代码中发生的事情。我不明白的部分是服务结构。服务结构是 APIClient 结构的包装器。当 NewAPIClient 被调用时,它使用内部的服务结构并复制到自身。我似乎无法解决这个问题。请指教并详细说明。谢谢你。

type APIClient struct {
cfg *Configuration

// Reuse a single struct instead of
// allocating one for each service on the heap.
common service

// API Services
AccountApi *AccountApiService
ContractApi *ContractApiService
FYIApi *FYIApiService
IBCustApi *IBCustApiService
MarketDataApi *MarketDataApiService
OrderApi *OrderApiService
PnLApi *PnLApiService
PortfolioApi *PortfolioApiService
PortfolioAnalystApi *PortfolioAnalystApiService
ScannerApi *ScannerApiService
SessionApi *SessionApiService
TradesApi *TradesApiService
}

type service struct {
client *APIClient
}

func NewAPIClient(cfg *Configuration) *APIClient {
if cfg.HTTPClient == nil {
cfg.HTTPClient = http.DefaultClient
}

c := &APIClient{}
c.cfg = cfg
c.common.client = c

c.AccountApi = (*AccountApiService)(&c.common)
c.ContractApi = (*ContractApiService)(&c.common)
c.FYIApi = (*FYIApiService)(&c.common)
c.IBCustApi = (*IBCustApiService)(&c.common)
c.MarketDataApi = (*MarketDataApiService)(&c.common)
c.OrderApi = (*OrderApiService)(&c.common)
c.PnLApi = (*PnLApiService)(&c.common)
c.PortfolioApi = (*PortfolioApiService)(&c.common)
c.PortfolioAnalystApi = (*PortfolioAnalystApiService)(&c.common)
c.ScannerApi = (*ScannerApiService)(&c.common)
c.SessionApi = (*SessionApiService)(&c.common)
c.TradesApi = (*TradesApiService)(&c.common)

return c
}

最佳答案

首先,请注意表达式 (*AccountApiService)(&c.common) 是一个显式 conversion :

A conversion changes the type of an expression to the type specified by the conversion.

有许多规则允许您将一种类型的表达式转换为另一种类型,但与您的用例相关的规则是:

  • ignoring struct tags (see below), x's type and T have identical underlying types.

所以赋值语句c.AccountApi = (*AccountApiService)(&c.common)可以这样解释:因为字段common类型service 表达式 &c.common*service 类型,然后该类型转换*AccountApiService 并将该转换表达式的结果分配给 c.AccountApi 字段。

正如我们在上面建立的那样,要使转换起作用,*AccountApiService*service 这两种类型必须具有相同的基础类型。因此,即使您没有为任何这些 XxxApiService 类型提供定义,也可以安全地假设,如果代码实际编译,它们都被定义为

type XxxApiService service

type XxxApiService struct {
client *APIClient
}

有效地为它们提供与服务的底层类型相同的底层类型。


你可能会问自己为什么不像正常人一样初始化各种服务,为什么不写这个

c.AccountApi = &AccountApiService{c}

相反?答案在 APIClientcommon 字段上方的注释中。

Reuse a single struct instead of allocating one for each service on the heap.

这意味着不是为每个服务字段分配新的 XxxApiService 实例,分配给 common 的值由所有服务字段共享。我认为这里的目的是资源/性能优化。


最后是赋值 c.common.client = cAPIClient 有一个名为 common 的字段,类型为 service,类型 service 有一个名为 的字段*APIClient 类型的客户端。这基本上允许客户端通过 common 字段持有对自身的引用,虽然这不是这里的主要目标,但这正是示例代码中发生的事情。基本上递归,APIClient 设计 AFAICT 的一个意想不到的功能,但它就在那里。

关于go - 重用结构以减少堆使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57646756/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com