Mi piace google golang, ma qualcuno potrebbe spiegare quale sia la logica per gli implementatori che hanno omesso una struttura di dati di base come set dalla libreria standard?
Una possibile ragione di questa omissione è che è davvero facile modellare insiemi con una mappa.
Per essere onesti, penso che sia un po 'troppo di supervisione, tuttavia guardando Perl, la storia è esattamente la stessa. In Perl ottieni liste e hashtables, in Vai ottieni array, slice e mappe. In Perl generalmente utilizzi una tabella hash per tutti i problemi relativi a un set, lo stesso vale per Go.
Esempio
per imitare una serie di elementi in Go, definiamo una mappa:
set := make(map[int]bool)
Aggiungere qualcosa è facile come:
i := valueToAdd()
set[i] = true
L'eliminazione di qualcosa è solo
delete(set, i)
E la potenziale goffaggine di questo costrutto è facilmente astratta:
type IntSet struct {
set map[int]bool
}
func (set *IntSet) Add(i int) bool {
_, found := set.set[i]
set.set[i] = true
return !found //False if it existed already
}
E delete and get può essere definito in modo simile, ho l'implementazione completa qui . Il maggiore svantaggio qui è il fatto che andare non ha generici. Tuttavia è possibile farlo con interface{}
nel qual caso avresti lanciato i risultati di get.
La risposta precedente funziona SOLO SE la chiave è di tipo built-in. Per completare la risposta precedente, ecco un modo per implementare un set i cui elementi sono tipi definiti dall'utente:
package math
// types
type IntPoint struct {
X, Y int
}
// set implementation for small number of items
type IntPointSet struct {
slice []IntPoint
}
// functions
func (p1 IntPoint) Equals(p2 IntPoint) bool {
return (p1.X == p2.X) && (p1.Y == p2.Y)
}
func (set *IntPointSet) Add(p IntPoint) {
if ! set.Contains(p) {
set.slice = append(set.slice, p)
}
}
func (set IntPointSet) Contains(p IntPoint) bool {
for _, v := range set.slice {
if v.Equals(p) {
return true
}
}
return false
}
func (set IntPointSet) NumElements() int {
return len(set.slice)
}
func NewIntPointSet() IntPointSet {
return IntPointSet{(make([]IntPoint, 0, 10))}
}
Penso che questo abbia a che fare con golang
focus sulla semplicità. set
s diventa davvero utile con difference
, intersection
, union
, issubset
e così via .. metodi. Forse golang
team ha ritenuto che sia troppo per una struttura di dati. Ma altrimenti un "set stupido" che ha solo add
, contains
e remove
può essere facilmente replicato con map
come spiegato da @jozefg.
Leggi altre domande sui tag programming-languages data-structures go