Imposta la struttura dei dati in Golang

63

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?

    
posta cobie 28.11.2012 - 01:02
fonte

3 risposte

63

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.

    
risposta data 28.11.2012 - 04:08
fonte
3

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))}
}
    
risposta data 16.02.2015 - 04:46
fonte
2

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.

    
risposta data 17.11.2015 - 05:40
fonte

Leggi altre domande sui tag