提问人:SelfLearnedNoob 提问时间:10/6/2022 更新时间:10/6/2022 访问量:158
如何在 Golang 中将自定义结构的一部分复制到其他结构
How do I copy part of a custom struct to a different struct in Golang
问:
我已经坚持了几个小时,希望你们中的一个人能帮助我找到一个优雅的解决方案。
基本上,我有以下结构:
type GetERC20TransferResponse struct {
Data struct {
Address string `json:"address"`
UpdatedAt time.Time `json:"updated_at"`
NextUpdateAt time.Time `json:"next_update_at"`
QuoteCurrency string `json:"quote_currency"`
ChainID int `json:"chain_id"`
Items []struct {
BlockSignedAt time.Time `json:"block_signed_at"`
BlockHeight int `json:"block_height"`
TxHash string `json:"tx_hash"`
TxOffset int `json:"tx_offset"`
Successful bool `json:"successful"`
FromAddress string `json:"from_address"`
FromAddressLabel interface{} `json:"from_address_label"`
ToAddress string `json:"to_address"`
ToAddressLabel interface{} `json:"to_address_label"`
Value string `json:"value"`
ValueQuote float64 `json:"value_quote"`
GasOffered int `json:"gas_offered"`
GasSpent int `json:"gas_spent"`
GasPrice int64 `json:"gas_price"`
FeesPaid interface{} `json:"fees_paid"`
GasQuote float64 `json:"gas_quote"`
GasQuoteRate float64 `json:"gas_quote_rate"`
Transfers []struct {
BlockSignedAt time.Time `json:"block_signed_at"`
TxHash string `json:"tx_hash"`
FromAddress string `json:"from_address"`
FromAddressLabel interface{} `json:"from_address_label"`
ToAddress string `json:"to_address"`
ToAddressLabel interface{} `json:"to_address_label"`
ContractDecimals int `json:"contract_decimals"`
ContractName string `json:"contract_name"`
ContractTickerSymbol string `json:"contract_ticker_symbol"`
ContractAddress string `json:"contract_address"`
LogoURL string `json:"logo_url"`
TransferType string `json:"transfer_type"`
Delta string `json:"delta"`
Balance interface{} `json:"balance"`
QuoteRate float64 `json:"quote_rate"`
DeltaQuote float64 `json:"delta_quote"`
BalanceQuote interface{} `json:"balance_quote"`
MethodCalls interface{} `json:"method_calls"`
} `json:"transfers"`
} `json:"items"`
Pagination struct {
HasMore bool `json:"has_more"`
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
TotalCount interface{} `json:"total_count"`
} `json:"pagination"`
} `json:"data"`
Error bool `json:"error"`
ErrorMessage interface{} `json:"error_message"`
ErrorCode interface{} `json:"error_code"`
现在,处理这些数据并不困难,但现在我正在尝试做一些我不确定是否可能的事情。基本上,我创建了另一个名为 Transfer 的结构:
type Transfer []struct {
BlockSignedAt time.Time `json:"block_signed_at"`
TxHash string `json:"tx_hash"`
FromAddress string `json:"from_address"`
FromAddressLabel interface{} `json:"from_address_label"`
ToAddress string `json:"to_address"`
ToAddressLabel interface{} `json:"to_address_label"`
ContractDecimals int `json:"contract_decimals"`
ContractName string `json:"contract_name"`
ContractTickerSymbol string `json:"contract_ticker_symbol"`
ContractAddress string `json:"contract_address"`
LogoURL string `json:"logo_url"`
TransferType string `json:"transfer_type"`
Delta string `json:"delta"`
Balance interface{} `json:"balance"`
QuoteRate float64 `json:"quote_rate"`
DeltaQuote float64 `json:"delta_quote"`
BalanceQuote interface{} `json:"balance_quote"`
MethodCalls interface{} `json:"method_calls"`
}
这只是回应的一部分。我需要的 Data.Items。现在我的问题是,如何从 GetERC20TransferReponse 结构中取出这部分,将其分离,然后返回。
流程是这样的:
- 查看 GetERC20TransferResponse 内部,查看 TransferType 的值。
- 根据 transfertype 执行操作/从响应中保存内容。Data.Items[1] / Transfer []struct 部分的 GetERC20TransferResponse
简而言之,非常优雅的是,当我调用检查 TransferType 是 0、1 还是 2 的函数时,它还将返回 GetERC20TransferResponse 结构的整个“Transfers”部分并返回它,这样我就不必再次访问该结构。
这是针对我正在开发的开源工具,出于速度原因,它需要在 Go 中(我相对较新)。
答:
0赞
Daniel Kiptoon
10/6/2022
#1
我建议首先将整个响应“GetERC20TransferResponse”分解为单独的结构体
// single transfer
type Transfer struct {
BlockSignedAt time.Time `json:"block_signed_at"`
TxHash string `json:"tx_hash"`
FromAddress string `json:"from_address"`
FromAddressLabel interface{} `json:"from_address_label"`
ToAddress string `json:"to_address"`
ToAddressLabel interface{} `json:"to_address_label"`
ContractDecimals int `json:"contract_decimals"`
ContractName string `json:"contract_name"`
ContractTickerSymbol string `json:"contract_ticker_symbol"`
ContractAddress string `json:"contract_address"`
LogoURL string `json:"logo_url"`
TransferType string `json:"transfer_type"`
Delta string `json:"delta"`
Balance interface{} `json:"balance"`
QuoteRate float64 `json:"quote_rate"`
DeltaQuote float64 `json:"delta_quote"`
BalanceQuote interface{} `json:"balance_quote"`
MethodCalls interface{} `json:"method_calls"`
}
//single ERC items
type ERCItems struct {
BlockSignedAt time.Time `json:"block_signed_at"`
BlockHeight int `json:"block_height"`
TxHash string `json:"tx_hash"`
TxOffset int `json:"tx_offset"`
Successful bool `json:"successful"`
FromAddress string `json:"from_address"`
FromAddressLabel interface{} `json:"from_address_label"`
ToAddress string `json:"to_address"`
ToAddressLabel interface{} `json:"to_address_label"`
Value string `json:"value"`
ValueQuote float64 `json:"value_quote"`
GasOffered int `json:"gas_offered"`
GasSpent int `json:"gas_spent"`
GasPrice int64 `json:"gas_price"`
FeesPaid interface{} `json:"fees_paid"`
GasQuote float64 `json:"gas_quote"`
GasQuoteRate float64 `json:"gas_quote_rate"`
Transfers []Transfer `json:"transfers"`
}
//response data
type Data struct {
Address string `json:"address"`
UpdatedAt time.Time `json:"updated_at"`
NextUpdateAt time.Time `json:"next_update_at"`
QuoteCurrency string `json:"quote_currency"`
ChainID int `json:"chain_id"`
Items []ERCItems `json:"items"`
Pagination struct {
HasMore bool `json:"has_more"`
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
TotalCount interface{} `json:"total_count"`
} `json:"pagination"`
}
//general response
type GetERC20TransferResponse struct {
Data Data `json:"data"`
Error bool `json:"error"`
ErrorMessage interface{} `json:"error_message"`
ErrorCode interface{} `json:"error_code"`
}
这使您可以对响应对象进行细粒度控制。之后,您可以简单地使用一个函数来检查模型以检查转移类型并根据需要选择转移,例如
func main() {
response := GetERC20TransferResponse{}
// get all items from the response
items := response.Data.Items
// slice to store transfers that match the required transfer type
transfers := make([]Transfer, 0)
// iterate through all items to and further iterate through all transfers adding
// the whole transfers if any matches the required transfer types
for _, item := range items {
for _, transfer := range item.Transfers {
if transfer.TransferType == "0" || transfer.TransferType == "1" || transfer.TransferType == "2" {
transfers = append(transfers, item.Transfers...)
break
}
}
}
}
根据需要重构
评论
0赞
SelfLearnedNoob
10/6/2022
很有意思,谢谢!将按照您的建议实施它。
评论