Menu
Coddy logo textTech

Reflection Temelleri

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

Yansıma, bir programın çalışma zamanında kendi yapısını incelemesine ve değiştirmesine olanak tanır. Go'nun reflect paketi bu olanağı sağlayarak türleri incelemenize, yapı alanlarını okumanıza ve yöntemleri dinamik olarak çağırmanıza imkân verir.

Yansıtmadaki iki temel tür reflect.Type ve reflect.Value’dur. Bunları reflect.TypeOf() ve reflect.ValueOf() kullanarak elde edersin:

import "reflect"

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Alice", Age: 30}

t := reflect.TypeOf(p)
v := reflect.ValueOf(p)

fmt.Println(t.Name())       // Person
fmt.Println(t.Kind())       // struct
fmt.Println(v.NumField())   // 2

Adlarını, türlerini ve değerlerini incelemek için yapı alanları üzerinde yineleme yapabilirsiniz:

for i := 0; i < t.NumField(); i++ {
    field := t.Field(i)
    value := v.Field(i)
    fmt.Printf("%s: %v\n", field.Name, value)
}
// Çıktı:
// Name: Alice
// Age: 30

Yansıma güçlüdür ancak bazı ödünleri beraberinde getirir: derleme zamanındaki tür denetimini devre dışı bırakır, doğrudan erişimden daha yavaş çalışır ve kodun anlaşılmasını zorlaştırır. Yansıma; JSON serileştirme, ORM eşleme veya türün derleme zamanında bilinmediği genel amaçlı yardımcı programlar oluşturma gibi görevlerde idareli kullanılmalıdır.

challenge icon

Görev

Kolay

Yansımayı kullanarak herhangi bir yapıyı inceleyen ve yapısını raporlayan bir yapı denetleyicisi oluşturalım! Bu, yansımanın pratik bir kullanım alanıdır: derleme zamanında türleri bilinmeyen türlerle çalışan yardımcı araçlar oluşturmak.

Kodunuzu iki dosyaya ayıracaksınız:

  • inspector.go: Yansıma tabanlı inceleme yardımcı programınızı oluşturun.

    Herhangi bir yapıyı incelemek için InspectStruct(v any) string paketini kullanan reflect işlevini oluşturun. İşleviniz aşağıdakileri içeren biçimlendirilmiş bir rapor döndürmelidir:

    • Yapının tür adı
    • Yapının türü ("struct" olmalıdır)
    • Alanların sayısı
    • Her alan için: alan adı, türü ve mevcut değeri

    Çıktı biçimi şöyle olmalıdır:

    Type: [TypeName]
    Kind: struct
    Fields: [count]
    - [FieldName] ([FieldType]): [Value]
    - [FieldName] ([FieldType]): [Value]
    ...

    Tür bilgilerini almak için reflect.TypeOf() ve alan değerlerine erişmek için reflect.ValueOf() kullanın. Alanlar arasında, meta veriler için tür üzerinde NumField() ve Field(i), gerçek değerler içinse değer üzerinde Field(i) kullanarak yineleyin.

  • main.go: Örnek yapıları tanımlayın ve denetleyicinizi kullanın.

    Bir yapı türünü (product veya employee) ve alan değerlerini okuyun, ardından uygun yapıyı oluşturup inceleyin.

    product için: Product (string), Name (float64) ve Price (bool) alanlarına sahip bir InStock yapısı oluşturun. Adı, fiyatı ve stok durumunu okuyun.

    employee için: Employee (int), ID (string) ve Name (string) alanlarına sahip bir Department yapısı oluşturun. ID'yi, adı ve departmanı okuyun.

    Oluşturulan yapıyı InspectStruct işlevine aktarın ve sonucu yazdırın.

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

  • 1. satır: Yapı türü (product veya employee)
  • Sonraki satırlar: Bu yapı türünün alan değerleri

Örneğin, aşağıdaki girdi verildiğinde:

product
Laptop
999.99
true

Çıktınız şöyle olmalıdır:

Type: Product
Kind: struct
Fields: 3
- Name (string): Laptop
- Price (float64): 999.99
- InStock (bool): true

Ve aşağıdaki girdi verildiğinde:

employee
42
Alice Johnson
Engineering

Çıktınız şöyle olmalıdır:

Type: Employee
Kind: struct
Fields: 3
- ID (int): 42
- Name (string): Alice Johnson
- Department (string): Engineering

Ve aşağıdaki girdi verildiğinde:

product
Headphones
79.50
false

Çıktınız şöyle olmalıdır:

Type: Product
Kind: struct
Fields: 3
- Name (string): Headphones
- Price (float64): 79.5
- InStock (bool): false

Denetleyicinizin, yapılarını önceden bilmeden farklı yapı türleriyle nasıl çalıştığına dikkat edin. Yansımanın gücü budur! Aynı InspectStruct işlevi hem Product hem de Employee yapılarını dinamik olarak işler.

Kendin dene

package main

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

// Name, Price ve InStock alanlarına sahip Product struct'ı
type Product struct {
	Name    string
	Price   float64
	InStock bool
}

// ID, Name ve Department alanlarına sahip Employee struct'ı
type Employee struct {
	ID         int
	Name       string
	Department string
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Struct türünü oku
	structType, _ := reader.ReadString('\n')
	structType = strings.TrimSpace(structType)

	if structType == "product" {
		// Product alanlarını oku
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		priceStr, _ := reader.ReadString('\n')
		priceStr = strings.TrimSpace(priceStr)
		price, _ := strconv.ParseFloat(priceStr, 64)

		inStockStr, _ := reader.ReadString('\n')
		inStockStr = strings.TrimSpace(inStockStr)
		inStock, _ := strconv.ParseBool(inStockStr)

		// TODO: Okunan değerlerle bir Product struct'ı oluştur
		// TODO: InspectStruct'ı product ile çağır ve sonucu yazdır

	} else if structType == "employee" {
		// Employee alanlarını oku
		idStr, _ := reader.ReadString('\n')
		idStr = strings.TrimSpace(idStr)
		id, _ := strconv.Atoi(idStr)

		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		department, _ := reader.ReadString('\n')
		department = strings.TrimSpace(department)

		// TODO: Okunan değerlerle bir Employee struct'ı oluştur
		// TODO: InspectStruct'ı employee ile çağır ve sonucu yazdır

	}
}
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