Тут сильно зависит от того, как вы будете использовать данные.
Например, если вы во все функции передаёте players
someFunc1(players)
someFunc2(players)
someFunc3(players)
тогда указатели на конкретного player'a использовать особо смысла нет, от этого будет даже хуже, т.к. при создании нового player'a (при взятии адреса) будет задействован сборщик мусора, что вызовет бесполезную доп. нагрузку.
Если же player структура не маленькая или их очень много, и обработка будет происходить каждого player'a в отдельности + при этом будет использоваться много разных функций, например вот так
func main() {
var players[] *Player
players = append(players, &Player{Id: 1, Name: "Bob"})
...
players = append(players, &Player{Id: 100, Name: "Bob"})
for i := range players {
someFunc1(players[i])
someFunc2(players[i])
someFunc3(players[i])
someFunc4(players[i])
// или одна из someFunc вызывает еще какие то функции и передаёт players туда
}
}
в этом случае вы получите выигрыш в производительности за счёт того, что при вызове каждой функции будет копироваться лишь указатель (8байт на 64битных процессорах) вместо всей структуры
Если точнее - вы получите доп. нагрузку за счёт того, что будет задействован сборщик мусора, но за счёт того, что вместо большого объёма данных при каждом вызове функции будет копироваться лишь указатель - вы получите выигрыш, который нивелирует проигрыш от сборщика мусора.
На всякий случай о том, когда есть смысл использовать указатель, а когда нет
https://qna.habr.com/q/1046708#answer_2019152