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 (Reflection), bir programın kendi yapısını çalışma zamanında incelemesine ve değiştirmesine olanak tanır. Go'nun reflect paketi bu yeteneği sağlayarak; türleri incelemenize, struct alanlarını okumanıza ve metotları dinamik olarak çağırmanıza imkan tanır.

Yansımadaki (reflection) iki temel tür reflect.Type ve reflect.Value'dur. Bunları reflect.TypeOf() ve reflect.ValueOf() kullanarak elde edersiniz:

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

Struct alanlarının adlarını, türlerini ve değerlerini incelemek için bu alanlar üzerinde döngü kurabilirsiniz:

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

Reflection güçlüdür ancak beraberinde bazı ödünler getirir: derleme zamanı tür denetimini atlar, doğrudan erişimden daha yavaş çalışır ve kodun anlaşılmasını zorlaştırır. JSON marshaling, ORM eşleme veya türün derleme zamanında bilinmediği jenerik yardımcı programlar oluşturma gibi görevler için idareli kullanın.

challenge icon

Görev

Kolay

Herhangi bir struct'ı incelemek ve yapısını raporlamak için yansıma (reflection) kullanan bir struct denetçisi (inspector) oluşturalım! Bu, yansıma için pratik bir kullanım örneğidir; derleme zamanında bilinmeyen türlerle çalışan yardımcı araçlar oluşturmak.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • inspector.go: Yansıma tabanlı denetleme aracınızı oluşturun.

    Kendisine iletilen herhangi bir struct'ı incelemek için reflect paketini kullanan bir InspectStruct(v any) string fonksiyonu oluşturun. Fonksiyonunuz şunları içeren biçimlendirilmiş bir rapor döndürmelidir:

    • Struct'ın tür adı
    • Struct'ın türü (kind) ("struct" olmalıdır)
    • Alan (field) sayısı
    • Her alan için: alan adı, türü ve mevcut değeri

    Çıktı formatı şu şekilde 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 gezinmek için NumField(), meta veriler için tür üzerinde Field(i) ve gerçek değerler için değer üzerinde Field(i) kullanın.

  • main.go: Örnek struct'lar tanımlayın ve denetçinizi kullanın.

    Bir struct türünü (product veya employee) ve alan değerlerini okuyun, ardından uygun struct'ı oluşturun ve denetleyin.

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

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

    Oluşturulan struct'ı InspectStruct fonksiyonuna gönderin ve sonucu yazdırın.

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

  • Satır 1: Struct türü (product veya employee)
  • Sonraki satırlar: O struct türü için alan değerleri

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

product
Laptop
999.99
true

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

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

Ve şu girdi verildiğinde:

employee
42
Alice Johnson
Engineering

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

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

Ve şu girdi verildiğinde:

product
Headphones
79.50
false

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

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

Denetçinizin, yapılarını önceden bilmeden farklı struct türleriyle nasıl çalıştığına dikkat edin; yansımanın gücü budur! Aynı InspectStruct fonksiyonu hem Product hem de Employee struct'larını dinamik olarak işler.

Kopya kağıdı

reflect paketi, programların çalışma zamanında kendi yapılarını incelemesine ve değiştirmesine olanak tanır.

İki temel tür, reflect.TypeOf() ve reflect.ValueOf() kullanılarak elde edilen reflect.Type ve reflect.Value'dur:

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 struct alanları üzerinde döngü kurun:

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 (Reflection), derleme zamanı tür denetimini atlar, doğrudan erişimden daha yavaş çalışır ve kodun anlaşılmasını zorlaştırır. JSON marshaling, ORM eşleme veya türün derleme zamanında bilinmediği genel amaçlı araçlar (generic utilities) oluşturma gibi görevler için kullanın.

Kendin dene

package main

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

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

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

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

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

	if structType == "product" {
		// Ürün 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 yapısı oluşturun
		// TODO: Ürün ile InspectStruct fonksiyonunu çağırın ve sonucu yazdırın

	} else if structType == "employee" {
		// Çalışan 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 yapısı oluşturun
		// TODO: Çalışan ile InspectStruct fonksiyonunu çağırın ve sonucu yazdırı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