Google golang'ı gerçekten seviyorum, ancak bazıları standart kütüphaneden setler gibi temel bir veri yapısını bırakmış olan uygulayıcıların mantığının ne olduğunu açıklayabilir mi?
Google golang'ı gerçekten seviyorum, ancak bazıları standart kütüphaneden setler gibi temel bir veri yapısını bırakmış olan uygulayıcıların mantığının ne olduğunu açıklayabilir mi?
Yanıtlar:
Bu ihmalin olası bir nedeni, kümeleri bir harita ile modellemenin gerçekten kolay olmasıdır.
Dürüst olmak gerekirse, sanırım biraz da bir gözetim, ancak Perl'e bakıldığında, hikaye tamamen aynı. Perl'de listeler ve hashtables alırsınız, Go'da diziler, dilimler ve haritalar alırsınız. Perl'de genellikle bir setle ilgili her türlü problem için bir karma tablo kullanırsınız, aynısı Go için de geçerlidir.
Örnek
Go'da ayarlanmış bir bölümü taklit etmek için bir harita tanımlarız:
set := make(map[int]bool)
Bir şey eklemek kadar kolaydır:
i := valueToAdd()
set[i] = true
Bir şeyi silmek sadece
delete(set, i)
Ve bu yapının potansiyel garipliği kolayca soyutlanabilir:
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
}
Ve sil ve al benzer şekilde tanımlanabilir, burada tam bir uygulama var . Buradaki en büyük dezavantaj, gitmenin jenerik olmaması. Bununla birlikte interface{}
, bu durumda bunun sonucunu çıkarmanız gerekebilir.
map[int]bool
kullanabilirsiniz map[int]struct{}
. Sonuncuyu tercih ederim.
map[int]struct{}
.. struct{}
0 bayt alır.
map[int]struct{}
size yapamaz if mymap["key"] {
üyelik için kontrol etmek. Google, kullanılmasını önerirbool
("Bir küme uygulanabilir" ifadesini arayın).
Bunun golang
sadeliğe odaklanmakla ilgisi olduğunu düşünüyorum . set
gerçekten kullanışlı hale s difference
, intersection
, union
, issubset
, vb .. yöntemler. Belki de golang
ekip bunun bir veri yapısı için çok fazla olduğunu hissetti. Ancak, aksi takdirde @jozefg tarafından açıklandığı gibi kolayca sahip add
olan contains
ve remove
kolaylıkla çoğaltılabilen bir "aptal set" map
.
Önceki cevap, SADECE anahtarın yerleşik bir tip olması durumunda işe yarar. Önceki cevabı tamamlamak için, öğeleri kullanıcı tanımlı türlerden oluşan bir kümeyi uygulamanın bir yolu:
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))}
}
type mySet map[IntPoint]bool
mükemmel çalışıyor. Bütün bunlar bir harita kullanılan anahtar tip istendiğini olduğunu o olduğunu ==
ve!=
. Yapı tiplerinin eşitliği iyi tanımlanmış, Equals
yönteminiz adil olmalı p1 == p2
.
Contains
doğrusal zaman aMap[]
alır, sabit zaman alır. Daha iyi bir çözüm, dahili olarak her üyenin içeriğini temel alan benzersiz bir anahtar oluşturur ve map
türün sağladığı sabit zamanlı sorgulamayı kullanır . Önbellek davranışını, vs. dikkate alan daha hızlı çözümler de var.