Давайте рассмотрим только эти части:
var tradeArray []Trade
// code that fills in `tradeArray` -- correct, and omitted here
for _, trade := range tradeArray {
internal := InternalTrade{
Id: strconv.Itoa(rand.Intn(1000000)),
Trade: &trade,
}
submit := TradeSubmitted{
TradeId: internal.Id,
ClientTradeId: trade.ClientTradeId ,
}
submitArray = append(submitArray, submit)
trades = append(trades, internal)
}
Эти for
l oop, как вы видели, не работают так, как вы хотите. Вот его вариант, который отчасти похож, за исключением того, что переменная trade
имеет область действия, которая выходит за пределы for
l oop:
var trade Trade
for i := range tradeArray {
trade = tradeArray[i]
internal := InternalTrade{
Id: strconv.Itoa(rand.Intn(1000000)),
Trade: &trade,
}
// do correct stuff with `internal`
}
Обратите внимание, что каждый объект internal
указывает на одиночная общая переменная trade
, значение которой перезаписывается при каждой поездке через l oop. В результате все они указывают на один из последнего путешествия через l oop.
Ваше исправление само по себе нормально: каждое путешествие через l oop вы делаете переменную new (другую) p
и используйте &p
, чтобы у каждого internal.Trade
был свой указатель на свою копию. Вы также можете просто сделать trade := trade
внутри l oop, чтобы создать новую уникальную переменную trade
. Тем не менее, в этом конкретном случае, возможно, имеет смысл переписать l oop следующим образом:
for i := range tradeArray {
internal := InternalTrade{
Id: strconv.Itoa(rand.Intn(1000000)),
Trade: &tradeArray[i],
}
// do correct stuff with `internal`
}
То есть у вас уже есть len(tradeArray)
различные Trade
объекты: заголовок слайса tradeArray
предоставляет вам доступ к каждому экземпляру tradeArray[i]
, хранящемуся в базовом массиве. Вы можете просто указать на них напрямую.
У этого подхода есть свои преимущества и недостатки. Большим преимуществом является то, что вы не переписываете каждую сделку вообще: вы просто используете те из массива, который охватывает заголовок слайса, который был размещен внутри функции json
Decode
. Большим недостатком является то, что этот базовый массив нельзя собирать, пока вы сохраняете любой указатель на любой его элементов. Этот недостаток может вообще не иметь стоимости, в зависимости от структуры оставшегося кода, но если он является недостатком, рассмотрите объявление tradeArray
как:
var tradeArray []*Trade
, чтобы Функция json
Decode
распределяет каждую из них по отдельности, и вы можете указывать на них по одной, не форсируя сохранение всей коллекции.