Menu
Coddy logo textTech

Generic Struct'lar

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 70 / 107.

Tıpkı fonksiyonlar gibi, struct'lar da tür parametrelerine sahip olabilir. Jenerik struct, tür güvenliğini korurken herhangi bir türle çalışan veri yapıları oluşturmanı sağlar. Bu, yığınlar, kuyruklar veya anahtar-değer çiftleri gibi yeniden kullanılabilir kapsayıcılar oluşturmak için idealdir.

Genel bir yapı tanımlamak için tür parametresini yapı adının sonuna yerleştirin:

type Box[T any] struct {
    Value T
}

func main() {
    intBox := Box[int]{Value: 42}
    strBox := Box[string]{Value: "hello"}
    
    fmt.Println(intBox.Value)  // 42
    fmt.Println(strBox.Value)  // hello
}

Genel işlevlerin aksine, genel bir yapı örneği oluştururken türü açıkça belirtmelisiniz. Go, türü yalnızca bağlamdan çıkaramaz.

Genel struct'lar birden fazla tür parametresine sahip olabilir; bu da onları çiftler veya eşlemeler gibi yapılar için ideal kılar:

type Pair[K, V any] struct {
    Key   K
    Value V
}

p := Pair[string, int]{Key: "age", Value: 25}
fmt.Printf("%s: %d\n", p.Key, p.Value)  // age: 25

Depolanan türlerin belirli işlemleri desteklemesini sağlamak için kısıtlamalar da uygulayabilirsiniz:

type NumberBox[T int | float64] struct {
    Value T
}

nb := NumberBox[float64]{Value: 3.14}

Jenerik yapılar, Go'da tip güvenli ve yeniden kullanılabilir veri yapıları oluşturmanın temelini oluşturur. Bir sonraki derste, bu jenerik tipler üzerinde metotların nasıl tanımlanacağını öğreneceksiniz.

challenge icon

Görev

Kolay

Farklı türdeki öğeleri takip edebilen genel bir envanter sistemi oluşturalım! Her türle çalışırken tam tür güvenliğini koruyan yeniden kullanılabilir kapsayıcı yapıları oluşturacaksın.

Kodunu iki dosyaya ayıracaksın:

  • inventory.go: Genel kapsayıcı yapılarını tanımla.

    İki alana sahip genel bir struct Item[T any] oluştur: Name (string) ve Data (T türünde). Bu, esnek bir türde ilişkili veriye sahip herhangi bir öğeyi temsil eder.

    Container[T any] dilimini tutan tek bir Items alanına sahip genel bir struct Item[T] oluştur. Bu kapsayıcı, aynı veri türündeki birden çok öğeyi depolayabilir.

    Üç alana sahip kısıtlanmış bir genel struct PricedItem[T int | float64] oluştur: Name (string), Quantity (int) ve Price (T türünde). Kısıtlama, fiyatların her zaman sayısal olmasını sağlar.

    Boş bir Container oluşturup işaretçisini döndüren NewContainer[T any]() *Container[T] işlevini uygula.

    Add üzerinde bir *Container[T] yöntemi uygula. Bu yöntem bir ad (string) ve veri (T) almalı, bir Item oluşturmalı ve bunu kapsayıcının Items dilimine eklemelidir.

    Count üzerinde, kapsayıcıdaki öğe sayısını döndüren bir Container[T] yöntemi uygula.

  • main.go: Genel yapılarını farklı türlerle göster.

    Bir öğe türü (string, int veya priced) oku, ardından bir sayı ve öğe ayrıntılarını oku.

    string türü için: ad ve string verisi çiftlerini oku. Bir Container[string] oluştur, tüm öğeleri ekle, ardından her öğeyi [Name]: [Data] biçiminde ve sonrasında toplam sayıyı yazdır.

    int türü için: ad ve tamsayı verisi çiftlerini oku. Bir Container[int] oluştur, tüm öğeleri ekle, ardından her öğeyi [Name]: [Data] biçiminde ve sonrasında toplam sayıyı yazdır.

    priced türü için: ad, miktar ve fiyatı (float olarak) üçlüler hâlinde oku. Doğrudan PricedItem[float64] örnekleri oluştur ve her birini fiyat bir ondalık basamak gösterecek şekilde [Name] x[Quantity] @ [Price] biçiminde yazdır.

    Sayı satırını şu şekilde yazdır: Total items: [count]

Aşağıdaki girdiler sağlanacaktır:

  • 1. satır: Öğe türü (string, int veya priced)
  • 2. satır: Öğe sayısı (tamsayı)
  • Sonraki satırlar: Türe göre öğe ayrıntıları

Örneğin, şu girdi verildiğinde:

string
3
Book
Fiction Novel
Pen
Blue Ink
Notebook
Lined Paper

Çıktın şu şekilde olmalıdır:

Book: Fiction Novel
Pen: Blue Ink
Notebook: Lined Paper
Total items: 3

Şu girdi verildiğinde:

int
2
Apples
50
Oranges
30

Çıktın şu şekilde olmalıdır:

Apples: 50
Oranges: 30
Total items: 2

Şu girdi verildiğinde:

priced
2
Widget
10
19.99
Gadget
5
49.50

Çıktın şu şekilde olmalıdır:

Widget x10 @ 19.9
Gadget x5 @ 49.5
Total items: 2

Aynı Container yapısının hem dizelerle hem de tamsayılarla sorunsuz biçimde çalıştığına, PricedItem yapısının ise fiyatlar için yalnızca sayısal türlerin kullanılabilmesini sağlamak üzere bir kısıtlama kullandığına dikkat et. Bu genel struct'ların örneklerini oluştururken tür parametresini açıkça belirtmelisin.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Öğe türünü oku
	scanner.Scan()
	itemType := scanner.Text()
	
	// Sayısı oku
	scanner.Scan()
	count, _ := strconv.Atoi(scanner.Text())
	
	switch itemType {
	case "string":
		// TODO: NewContainer kullanarak bir Container[string] oluşturun
		// TODO: 'count' kadar öğe okuyun (her birinin adı bir satırda, verisi sonraki satırda)
		// TODO: Her öğeyi konteynere ekleyin
		// TODO: Her öğeyi "[Name]: [Data]" şeklinde yazdırın
		// TODO: Count metodunu kullanarak "Total items: [count]" yazdırın
		
	case "int":
		// TODO: NewContainer kullanarak bir Container[int] oluşturun
		// TODO: 'count' kadar öğe okuyun (her birinin adı bir satırda, tam sayı verisi sonraki satırda)
		// TODO: Her öğeyi konteynere ekleyin
		// TODO: Her öğeyi "[Name]: [Data]" şeklinde yazdırın
		// TODO: Count metodunu kullanarak "Total items: [count]" yazdırın
		
	case "priced":
		// TODO: PricedItem[float64] örneklerini tutmak için bir slice oluşturun
		// TODO: 'count' kadar öğe okuyun (her birinin adı, miktarı ve fiyatı ayrı satırlarda)
		// TODO: Her biri için PricedItem[float64] oluşturun ve slice'a ekleyin
		// TODO: Her öğeyi, fiyat bir ondalık basamak gösterecek şekilde "[Name] x[Quantity] @ [Price]" olarak yazdırın
		// TODO: "Total items: [count]" yazdırın
	}
	
	_ = scanner // Girdiyi okumak için scanner kullanın
	_ = count   // Döngü için count kullanın
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online Go derleyicisi