Struct İşaretçileri
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 20 / 107.
Yapılarla çalışırken, büyük veri yapılarını kopyalamaktan kaçınmak ve özgün yapıyı değiştirmek için genellikle işaretçiler kullanırsın. Bir yapıya işaretçi, o yapı örneğinin bellek adresini tutar.
Mevcut bir struct üzerinde & operatörünü kullanarak veya adres operatörünü doğrudan bir struct değişmez değeriyle kullanarak bir struct işaretçisi oluşturabilirsin.
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ştur
ptr2 := &Person{Name: "Bob", Age: 25}Go, bir işaretçi üzerinden struct alanlarına erişirken kullanışlı bir kısayol sağlar. (*ptr).Name yazmak yerine doğrudan ptr.Name yazabilirsiniz. Go, işaretçinin referansını sizin için otomatik olarak kaldırır.
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 dereferenceBu otomatik başvurudan çıkarma işlemi, alanlar değiştirilirken de geçerlidir. İşaretçi aracılığıyla yapılan değişiklikler özgün yapıyı etkiler.
p := Person{Name: "Alice", Age: 30}
ptr := &p
ptr.Age = 31 // orijinali değiştirir
fmt.Println(p.Age) // 31Struct işaretçileri, Go'nun OOP kalıplarında temel öneme sahiptir. Metotların alıcı durumunu değiştirmesini sağlar, büyük struct'ların işlevlere verimli bir şekilde aktarılmasına olanak tanır ve ağaçlar ile listeler gibi bağlantılı veri yapıları oluşturmanın temelini oluşturur.
Görev
KolayStruct işaretçilerinin özgün verileri verimli bir şekilde değiştirmenize nasıl olanak tanıdığını gösteren bir banka hesabı sistemi oluşturalım. İşaretçi işlemleri aracılığıyla güncellenebilen bir hesap oluşturacaksınız.
Kodunuzu iki dosya arasında düzenleyeceksiniz:
account.go:BankAccount(string),Owner(float64) veBalance(string) alanlarına sahip birAccountNumberstruct'ı tanımlayın. Sahip adını ve hesap numarasını parametre olarak alan ve başlangıç bakiyesi 0 olan yeni birNewAccount'a işaretçi döndürenBankAccountadlı bir işlev oluşturun. Ayrıca birDepositişaretçisi ile bir miktarı alan, ardından işaretçi üzerinden bu miktarı hesabın bakiyesine ekleyen bir*BankAccountişlevi oluşturun.main.go: Hesap bilgilerini girdiden okuyun, kurucu işlevinizi (bir işaretçi döndürür) kullanarak bir hesap oluşturun, işaretçiyi kullanarak para yatırın ve bakiyenin değiştirildiğini doğrulamak için hesap ayrıntılarını görüntüleyin.
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Sahip adı
- 2. satır: Hesap numarası
- 3. satır: Para yatırma miktarı (float)
Çıktı biçimi:
Account: [AccountNumber]
Owner: [Owner]
Balance: [Balance]Örneğin, John Smith, ACC-12345 ve 500.50 verildiğinde çıktınız şu şekilde olmalıdır:
Account: ACC-12345
Owner: John Smith
Balance: 500.50NewAccount işlevinizin *BankAccount operatörünü kullanarak & döndürmesi gerektiğini ve Deposit işlevinizin Go'nun otomatik başvuru kaldırma özelliğini kullanarak bakiyeyi doğrudan işaretçi üzerinden değiştirebileceğini unutmayın (örneğin account.Balance yerine (*account).Balance).
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]
}
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ı3İş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 PoolKendi başına pratik yap: Online Go derleyicisi