Pointers 在结构片上循环并更新值

Pointers 在结构片上循环并更新值,pointers,go,struct,slice,Pointers,Go,Struct,Slice,我从源A获取数据,并将其存储在结构片中,如下所示: type ProductPrice struct { Type string Sku string UnitPrice string PriceList string standardPrice string specialPrice string specialStart string specialEnd stri

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

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
}
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获取一些数据,并将其存储在结构片中,如下所示:

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
}
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中的结构片

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
结构切片?

在处理需要修改的值时,至少在我看来,最好使用指针。他们会让你的生活更轻松

因此,不是:

func getProductPricesFromDatabase(instance string) []ProductPrice {
    // ...
    var productPrices []ProductPrice

    for rows.Next() {
        var product = ProductPrice{}

        // ...
    }    
    return productPrices
}
我建议您重构代码,以便:

func getProductPricesFromDatabase(instance string) []*ProductPrice {
    // ...
    var productPrices []*ProductPrice

    for rows.Next() {
        var product = new(ProductPrice)

        // ...
    }    
    return productPrices
}
现在对
getContractProductPricesFromDatabase
执行相同的操作,最后将参数类型更新为
processProductPricesFromDatabase
函数:

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
}

另一种选择是,如果希望继续使用非指针类型,可以通过索引到切片中来直接修改切片引用的值

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
}

您需要循环使用
[]*ProductPrice
,即指针,以便能够修改它们,否则您在循环中看到的是您已经知道的每个切片元素的副本。或者使用索引
productPrices[i]。单价=…
@mkopriva您能给我举个例子吗?我不知道如何按照你的建议进行重构?或者@mkopriva您的评论属于答案。谢谢您的指导!工作完美。