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]boolkullanabilirsiniz 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 golangsadeliğe odaklanmakla ilgisi olduğunu düşünüyorum . setgerçekten kullanışlı hale s difference, intersection, union, issubset, vb .. yöntemler. Belki de golangekip bunun bir veri yapısı için çok fazla olduğunu hissetti. Ancak, aksi takdirde @jozefg tarafından açıklandığı gibi kolayca sahip addolan containsve removekolaylı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]boolmü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ış, Equalsyönteminiz adil olmalı p1 == p2.
Containsdoğ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 maptürün sağladığı sabit zamanlı sorgulamayı kullanır . Önbellek davranışını, vs. dikkate alan daha hızlı çözümler de var.