Menu
Coddy logo textTech

Struct İşaretçileri

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

Struct'larla çalışırken, büyük veri yapılarını kopyalamaktan kaçınmak ve orijinal struct'ı değiştirmek için genellikle pointer'lar kullanırsınız. Bir struct pointer'ı, o struct örneğinin bellek adresini tutar.

Mevcut bir struct üzerinde & operatörünü kullanarak veya bir struct literal ile doğrudan adres operatörünü kullanarak bir struct işaretçisi (pointer) oluşturabilirsiniz.

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Alice", Age: 30}
ptr := &p  // mevcut struct'a işaretçi

// Veya doğrudan oluşturun
ptr2 := &Person{Name: "Bob", Age: 25}

Go, bir işaretçi aracılığıyla struct alanlarına erişirken kullanışlı bir kısayol sağlar. (*ptr).Name yazmak yerine, doğrudan ptr.Name yazabilirsiniz. Go, işaretçiyi sizin için otomatik olarak dereference eder.

ptr := &Person{Name: "Alice", Age: 30}

// Her ikisi de aynı şekilde çalışır
fmt.Println((*ptr).Name)  // açık dereference
fmt.Println(ptr.Name)     // otomatik dereference

Bu otomatik başvuru çözme (dereferencing) işlemi, alanlar değiştirilirken de geçerlidir. İşaretçi (pointer) üzerinden yapılan değişiklikler orijinal yapıyı (struct) etkiler.

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

ptr.Age = 31           // orijinali değiştirir
fmt.Println(p.Age)     // 31

Struct işaretçileri, Go'nun OOP desenlerinde temel öneme sahiptir. Bunlar, metotların alıcı (receiver) durumunu değiştirmesine olanak tanır, büyük struct'ların fonksiyonlara verimli bir şekilde aktarılmasını sağlar ve ağaçlar ile listeler gibi bağlı veri yapıları oluşturmanın temelini oluşturur.

challenge icon

Görev

Kolay

Struct pointer'ların orijinal verileri verimli bir şekilde değiştirmenize nasıl olanak tanıdığını gösteren bir banka hesabı sistemi oluşturalım. Pointer işlemleri aracılığıyla güncellenebilen bir hesap oluşturacaksınız.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • account.go: Owner (string), Balance (float64) ve AccountNumber (string) alanlarına sahip bir BankAccount struct'ı tanımlayın. Parametre olarak bir sahip adı ve hesap numarası alan ve 0 başlangıç bakiyesiyle yeni bir BankAccount pointer'ı döndüren NewAccount adında bir fonksiyon oluşturun. Ayrıca bir *BankAccount pointer'ı ve bir miktar alan, ardından bu miktarı pointer aracılığıyla hesabın bakiyesine ekleyen bir Deposit fonksiyonu oluşturun.
  • main.go: Girdiden hesap bilgilerini okuyun, oluşturucu fonksiyonunuzu (bir pointer döndüren) kullanarak bir hesap oluşturun, pointer'ı kullanarak bir para yatırma işlemi yapın ve bakiyenin değiştirildiğini onaylamak için hesap ayrıntılarını görüntüleyin.

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

  • Satır 1: Sahip adı (Owner name)
  • Satır 2: Hesap numarası (Account number)
  • Satır 3: Yatırılacak miktar (Deposit amount - float)

Çıktı formatı:

Account: [AccountNumber]
Owner: [Owner]
Balance: [Balance]

Örneğin, John Smith, ACC-12345 ve 500.50 verildiğinde, çıktınız şöyle olmalıdır:

Account: ACC-12345
Owner: John Smith
Balance: 500.50

NewAccount fonksiyonunuzun & operatörünü kullanarak *BankAccount döndürmesi gerektiğini ve Deposit fonksiyonunuzun Go'nun otomatik dereferencing özelliği sayesinde (örneğin, (*account).Balance yerine account.Balance) bakiyeyi doğrudan pointer üzerinden değiştirebileceğini unutmayın.

Kopya kağıdı

Bir struct pointer'ı, bir struct örneğinin bellek adresini tutar. & operatörünü kullanarak struct pointer'ları oluşturun:

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Alice", Age: 30}
ptr := &p  // mevcut struct'a pointer

// Veya doğrudan oluşturun
ptr2 := &Person{Name: "Bob", Age: 25}

Go, bir pointer üzerinden struct alanlarına erişirken otomatik dereferencing (adres çözümleme) sağlar. (*ptr).Name yerine ptr.Name yazabilirsiniz:

ptr := &Person{Name: "Alice", Age: 30}

// Her ikisi de aynı şekilde çalışır
fmt.Println((*ptr).Name)  // açık dereference
fmt.Println(ptr.Name)     // otomatik dereference

Bir pointer üzerinden yapılan değişiklikler orijinal struct'ı etkiler:

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

ptr.Age = 31           // orijinali değiştirir
fmt.Println(p.Age)     // 31

Struct pointer'ları, metotların alıcı (receiver) durumunu değiştirmesine olanak tanır, büyük struct'ların fonksiyonlara verimli bir şekilde aktarılmasını sağlar ve bağlı veri yapılarının temelini oluşturur.

Kendin dene

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	
	// Sahip adını oku
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)
	
	// Hesap numarasını oku
	accountNumber, _ := reader.ReadString('\n')
	accountNumber = strings.TrimSpace(accountNumber)
	
	// Yatırılacak tutarı oku
	amountStr, _ := reader.ReadString('\n')
	amountStr = strings.TrimSpace(amountStr)
	amount, _ := strconv.ParseFloat(amountStr, 64)
	
	// TODO: NewAccount fonksiyonunu kullanarak yeni bir hesap oluşturun (bir işaretçi döndürür)
	
	// TODO: Hesap işaretçisini kullanarak Deposit fonksiyonu ile para yatırın
	
	// TODO: Hesap ayrıntılarını istenen formatta yazdırın:
	// Account: [AccountNumber]
	// Owner: [Owner]
	// Balance: [Balance]
}
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