Realmente me gusta google golang pero ¿podría alguien explicar cuál es la razón para que los implementadores hayan omitido una estructura de datos básica como los conjuntos de la biblioteca estándar?
Realmente me gusta google golang pero ¿podría alguien explicar cuál es la razón para que los implementadores hayan omitido una estructura de datos básica como los conjuntos de la biblioteca estándar?
Una posible razón para esta omisión es que es realmente fácil modelar conjuntos con un mapa.
Para ser honesto, creo que también es un descuido, sin embargo, mirando a Perl, la historia es exactamente la misma. En Perl obtienes listas y tablas hash, en Go obtienes matrices, cortes y mapas. En Perl, por lo general, utilizas una tabla hash para todos los problemas relacionados con un conjunto, lo mismo se aplica a Go.
Ejemplo
para imitar un conjunto de entradas en Go, definimos un mapa:
set := make(map[int]bool)
Agregar algo es tan fácil como:
i := valueToAdd()
set[i] = true
Eliminar algo es solo
delete(set, i)
Y la torpeza potencial de esta construcción se extrae fácilmente:
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
}
Y eliminar y obtener se pueden definir de manera similar, tengo la implementación completa aquí . La principal desventaja aquí es el hecho de que ir no tiene genéricos. Sin embargo, es posible hacerlo con interface{}
, en cuyo caso habrías obtenido los resultados de get.
La respuesta anterior funciona SOLAMENTE SI la clave es un tipo integrado. Para complementar la respuesta anterior, aquí hay una manera de implementar un conjunto cuyos elementos son tipos definidos por el usuario:
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))}
}
Creo que esto tiene que ver con el enfoque golang
en la simplicidad. set
s se vuelve realmente útil con los métodos difference
, intersection
, union
, issubset
, etc. Quizás el equipo de golang
consideró que es demasiado para una estructura de datos. Pero por lo demás, un "conjunto de tontos" que solo tiene add
, contains
y remove
se puede replicar fácilmente con map
como se explica en @jozefg.
Lea otras preguntas en las etiquetas programming-languages data-structures go
¶módulo de datos. Establecer () donde los datos Persona = Persona {nombre :: Int, dirección :: Int} derivando (Eq, Mostrar, Mostrar) import struct.pack # Nombres completos en el paquete struct [Nombre] (...) derivando (Mostrar, [Eq, Eq]) func n-scala. Persona {_ _ = P (P (Persona {nombre :: Cadena, dirección :: Cadena})), err = P (UnicodeError (mapa .. ""), parseJSON (str "Error de codificación de caracteres Unicode 5")), })} doc <- 1.3 UnoType main :: IO () main = printfn "================================ ==========================... Lee mas