sort.Interface Arayüzü
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 74 / 107.
sort paketi, arayüz tabanlı tasarımın bir başka mükemmel örneğini sunar. Özel bir koleksiyonu sıralamak için, türünüzün sort.Interface arayüzünü uygulaması gerekir:
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}Bu üç yöntem, sıralama algoritmasına ihtiyacı olan her şeyi sağlar: koleksiyonun uzunluğu, öğeleri karşılaştırmanın bir yolu ve onları yer değiştirmenin bir yolu. İşte özel yapı (struct) dilimlerini nasıl sıralanabilir hale getireceğiniz:
type Person struct {
Name string
Age int
}
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func main() {
people := []Person{
{"Alice", 30},
{"Bob", 25},
{"Carol", 35},
}
sort.Sort(ByAge(people))
fmt.Println(people)
// [{Bob 25} {Alice 30} {Carol 35}]
}Temel fikir, diliminize (slice) dayalı adlandırılmış bir tür (ByAge) oluşturmaktır. Bu, aynı veriler için farklı sıralama davranışları tanımlamanıza olanak tanır. Bunun yerine alfabetik olarak sıralamak için farklı bir Less uygulamasına sahip ByName oluşturabilirsiniz.
Türünüz sort.Interface arayüzünü karşıladığında; sort.Sort(), sort.Reverse() ve sort.IsSorted() ile otomatik olarak çalışır.
Görev
KolayGo'nin sort.Interface özelliğinin gücünü gösteren sıralanabilir bir ürün envanter sistemi kuralım! Bir Product türü oluşturacak ve aynı koleksiyonun farklı şekillerde sıralanmasına olanak tanıyan birden fazla sıralama stratejisi uygulayacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
product.go: Ürün türünüzü ve sıralama uygulamalarınızı tanımlayın.Üç alana sahip bir
Productyapısı (struct) oluşturun:Name(string),Price(float64) veQuantity(int).[]Producttemelinde iki isimlendirilmiş tür oluşturun:ByPrice- ürünleri fiyata göre artan düzende sıralamak içinByQuantity- ürünleri miktara göre azalan düzende (en yüksek miktar önce) sıralamak için
Her türün
sort.Interfacetarafından zorunlu kılınan üç metodu uygulaması gerekir:Len(),Less(i, j int)veSwap(i, j int).Lessmetodu, her tür için sıralama düzenini belirler.main.go: Ürün envanterinizi oluşturun ve sıralayın.Bir sıralama modu (
priceveyaquantity) okuyun, ardından bir sayı ve ardından ürün detaylarını okuyun. Her ürün üç satır olarak verilir: isim, fiyat ve miktar.Bir ürün dilimi (slice) oluşturun, moda göre uygun sıralama türünü kullanarak bunları sıralayın ve ardından her ürünü şu formatta yazdırın:
[Name]: $[Price] (x[Quantity])Fiyatları iki ondalık basamakla görüntüleyin.
Aşağıdaki girdiler sağlanacaktır:
- Satır 1: Sıralama modu (
priceveyaquantity) - Satır 2: Ürün sayısı
- Sonraki satırlar: Ürün detayları (isim, fiyat, miktar - her ürün için üç satır)
Örneğin, şu girdi verildiğinde:
price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25Çıktınız şöyle olmalıdır:
Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)Ve şu girdi verildiğinde:
quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25Çıktınız şöyle olmalıdır:
Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)Aynı ürün verilerinin sadece farklı bir isimlendirilmiş tür kullanılarak nasıl farklı şekilde sıralanabildiğine dikkat edin. Türleriniz sort.Interface arayüzünü karşıladığında, standart kütüphanedeki sort.Sort() ile sorunsuz bir şekilde çalışırlar.
Kopya kağıdı
sort paketi, türlerin sıralanabilir olması için sort.Interface arayüzünü uygulamasını gerektirir:
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}Özel bir dilimi (slice) sıralanabilir hale getirmek için, isimlendirilmiş bir tür oluşturun ve gerekli üç metodu uygulayın:
type Person struct {
Name string
Age int
}
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// Sort the collection
sort.Sort(ByAge(people))Farklı sıralama davranışları uygulamak için aynı dilim için birden fazla isimlendirilmiş tür oluşturabilirsiniz. Her tür, sıralama düzenini belirlemek için kendi Less metodunu tanımlar.
Bir tür sort.Interface arayüzünü karşıladığında; sort.Sort(), sort.Reverse() ve sort.IsSorted() fonksiyonları ile birlikte çalışabilir.
Kendin dene
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Sıralama modunu oku
var mode string
fmt.Fscanln(reader, &mode)
// Ürün sayısını oku
var count int
fmt.Fscanln(reader, &count)
// Ürünleri oku
products := make([]Product, count)
for i := 0; i < count; i++ {
name, _ := reader.ReadString('\n')
name = name[:len(name)-1] // Satır sonu karakterini kaldır
priceStr, _ := reader.ReadString('\n')
priceStr = priceStr[:len(priceStr)-1]
price, _ := strconv.ParseFloat(priceStr, 64)
qtyStr, _ := reader.ReadString('\n')
qtyStr = qtyStr[:len(qtyStr)-1]
quantity, _ := strconv.Atoi(qtyStr)
products[i] = Product{Name: name, Price: price, Quantity: quantity}
}
// TODO: Ürünleri moda göre sırala
// Eğer mod "price" ise, ByPrice tipini kullan
// Eğer mod "quantity" ise, ByQuantity tipini kullan
// Uygun tiple sort.Sort() fonksiyonunu kullan
// TODO: Her ürünü şu formatta yazdır:
// [Name]: $[Price] (x[Quantity])
// Fiyat formatlaması için %.2f ile fmt.Printf kullan
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı11Standart Kütüphane ve OOP
io.Reader ve io.Writersort.Interface Arayüzüfmt.Stringer ArayüzüStruct'lar ile encoding/jsonhttp.Handler ArayüzüÖzet - REST API Modelleri3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker Pool