登录
首页 >  Golang >  Go问答

迭代结构体切片并修改数值

来源:stackoverflow

时间:2024-03-13 18:18:25 461浏览 收藏

在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《迭代结构体切片并修改数值》,聊聊,希望可以帮助到正在努力赚钱的你。

问题内容

我从源 a 获取数据并将其存储在结构体中,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
type productprice struct {
    type          string
    sku           string
    unitprice     string
    pricelist     string
    standardprice string
    specialprice  string
    specialstart  string
    specialend    string
    pricingunit   string
    categorycode  string
    isonspecial   bool
}
 
func getproductpricesfromdatabase(instance string) []productprice {
    rows, err := mydbconnection.query(// my query here)
 
    if err != nil {
        log.fatal("there was an issue with the query for product price: ", err)
    }
 
    defer rows.close()
 
    var productprices []productprice
 
    for rows.next() {
        var product = productprice{}
        err := rows.scan(
            &product.type,
            &product.sku,
            &product.standardprice,
            &product.specialprice,
            &product.specialstart,
            &product.specialend,
            &product.pricingunit,
            &product.pricelist,
            &product.categorycode,
        )
        if err != nil {
            log.fatal("product price scan error: ", err)
        }
 
        productprices = append(productprices, product)
    }
 
    return productprices
}

然后我从源 b 获取一些数据并将其存储在结构体中,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
type contractproductprice struct {
    custid                 string
    priceby                string
    appliesto              string
    pricelist              string
    startdate              string
    enddate                string
    pricingadjustmenttype  string
    pricingadjustmentvalue string
    uselowest              string
}
 
func getcontractproductpricesfromdatabase(instance string) []contractproductprice {
    rows, err := mydbconnection.query(// my query here)
 
    if err != nil {
        log.fatal("there was an issue with the query for contract product price: ", err)
    }
 
    defer rows.close()
 
    var contractproductprices []contractproductprice
 
    for rows.next() {
        var product = contractproductprice{}
        err := rows.scan(
            &product.custid,
            &product.priceby,
            &product.appliesto,
            &product.pricelist,
            &product.startdate,
            &product.enddate,
            &product.pricingadjustmenttype,
            &product.pricingadjustmentvalue,
            &product.uselowest,
        )
        if err != nil {
            log.fatal("contract product price scan error: ", err)
        }
        contractproductprices = append(contractproductprices, product)
    }
 
    return contractproductprices
}

从源 b 获取数据后,我想用源 b 中的一些数据更新源 a 中的结构切片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
productPrices := getProductPricesFromDatabase(instance)
contractProductPrices := getContractProductPricesFromDatabase(instance)
 
processedProductPrices := processProductPricesFromDatabase(productPrices, contractProductPrices)
 
func processProductPricesFromDatabase(productPrices []ProductPrice, contractProductPrices []ContractProductPrice) []ProductPrice {
    // Loop over contact prices and update relevant product prices
    for _, contractPrice := range contractProductPrices {
        for _, product := range productPrices {
            if contractPrice.AppliesTo == product.Sku {
                product.UnitPrice = contractPrice.PricingAdjustmentValue
            }
        }
    }
 
    return productPrices
}

但是,运行后,processedproductprices 中的单价仍然为空。

通过我的搜索,我明白了问题所在; go 按值传递,所以我没有更新原始内存地址,因此值没有改变。 但是,我不明白/不知道我需要更改什么来解决这个问题,因为我正在使用一片结构而不是一个更简单的数字/字符串片等示例。

如何更新 productprices,以便当我返回它时,processedproductprices 等于更新的 productprices 结构切片?


解决方案


每当您处理需要修改的值时,最好(至少在我看来)使用指针。它们会让您的生活更轻松。

所以代替:

1
2
3
4
5
6
7
8
9
10
11
func getproductpricesfromdatabase(instance string) []productprice {
    // ...
    var productprices []productprice
 
    for rows.next() {
        var product = productprice{}
 
        // ...
    }   
    return productprices
}

我建议您将代码重构为:

1
2
3
4
5
6
7
8
9
10
11
func getproductpricesfromdatabase(instance string) []*productprice {
    // ...
    var productprices []*productprice
 
    for rows.next() {
        var product = new(productprice)
 
        // ...
    }   
    return productprices
}

现在对 getcontractproductpricesfromdatabase 执行相同的操作,最后将参数类型更新为 processproductpricesfromdatabase 函数:

1
2
3
4
5
6
7
8
9
10
11
func processproductpricesfromdatabase(productprices []*productprice, contractproductprices []*contractproductprice) []*productprice {
    // loop over contact prices and update relevant product prices
    for _, contractprice := range contractproductprices {
        for _, product := range productprices {
            if contractprice.appliesto == product.sku {
                product.unitprice = contractprice.pricingadjustmentvalue
            }
        }
    }
    return productprices
}

作为替代方案,如果您想继续使用非指针类型,可以通过索引直接修改切片引用的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func processProductPricesFromDatabase(productPrices []ProductPrice, contractProductPrices []ContractProductPrice) []ProductPrice {
    // Loop over contact prices and update relevant product prices
 
    for _, contractPrice := range contractProductPrices {
 
        for i, _ := range productPrices {
            if contractPrice.AppliesTo == productPrices[i].Sku {
                productPrices[i].UnitPrice = contractPrice.PricingAdjustmentValue
            }
        }
    }
 
    return productPrices
}

本篇关于《迭代结构体切片并修改数值》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>