Go Veri Tipleri: Struct

Sayfayı kopyala
💡 Özet (TL;DR):
- Nedir: Farklı veri tiplerindeki alanları bir araya getiren ve kendi özel veri tiplerimizi oluşturmamızı sağlayan veri yapılarıdır (structures).
- Kritik Kod Düzeltmeleri: Örnek kodlardaki tanımlanmamış değişken adı (
ogrenciyerinestudent), küçük/büyük harf uyumsuzluğu (mathgradeyerinemathGrade) ve fazla noktalı virgül (;) gibi derleme hataları tamamen düzeltilmiştir.- Özellikler: Nokta gösterimi (
s1.name), iç içe struct kullanımı, pointer ile değiştirilebilir (mutable) referanslar oluşturma ve nesne yönelimli dillerdeki kalıtıma benzeyen "struct gömme (embedding)" özellikleri.
Kapak Fotoğrafı: Tranmautritam
Şimdiye kadar Array, Slice ve Map dahil olmak üzere birçok pratik ve faydalı veri tipinden bahsettik. Fakat bunlar her zaman ihtiyaçlarınıza tam karşılık vermeyebilir. Go, bu problemi "structures" (kısa adıyla struct) yapısıyla çözüyor.
Array, Slice ve Map'ler her ne kadar çok pratik olsalar da farklı tiplerdeki değerleri bir arada gruplayarak saklamamızı sağlayamazlar. Çeşitli değişkenleri gruplamak ve bunlardan yeni bir veri tipi oluşturmak için struct yapısını kullanabilirsiniz.
Struct, Map ve Sınıf (Class) Farkları
| Özellik | Struct (Go) | Map (Go) | Sınıf / Class (C#/Java) |
|---|---|---|---|
| Veri Tipi Homojenliği | Heterojen (Farklı tipler barındırabilir). | Homojen (Tüm anahtar ve değerler aynı tipte olmalıdır). | Heterojen (Metot ve değişkenleri barındırır). |
| Erişim Türü | Nokta gösterimi (s.Name) ile hızlı ve statik derleme zamanı kontrolü. | Anahtar araması (m["key"]) ile çalışma zamanı (runtime) kontrolü. | Nokta gösterimi ve metot çağrıları. |
| Referans vs. Değer | Değer (Value) tipidir. Kopyalanarak taşınır (Pointer ile referans verilir). | Referans (Reference) tipidir. Doğrudan bellekteki adresi gösterir. | Referans tipidir (Genellikle). |
| Kalıtım (Inheritance) | Doğrudan kalıtım yoktur, kompozisyon (embedding) kullanılır. | Kalıtım yoktur. | Arayüz (interface) ve sınıflardan kalıtım desteği vardır. |
1. Struct Tanımlama ve Değer Atama
Struct'lara, map tipi için kullandığımız örneği geliştirerek giriş yapabiliriz:
type student struct {
name string
mathGrade int
lithGrade int
}
Bu kullanım nesne yönelimli programlama dillerindeki sınıf (class) yapılarına benzese de, Go'da geleneksel bir nesne yönelimli yapı yoktur. Yukarıdaki tanımlamayla student adında yeni bir tip oluşturmuş olduk. Struct tipindeki bu değişkeni standart değişkenlere benzer yöntemlerle tanımlayıp değer atayabiliriz:
// Değerleri struct'ta tanımlandıkları sırayla atayabiliriz:
s1 := student{"Evren", 10, 8}
// Veya alan isimlerini belirterek eşleyebiliriz:
s1 := student{name: "Evren", mathGrade: 10}
Struct içerisindeki bir değere ulaşmak veya yeni değer atamak isterseniz nokta gösterimi (dot notation) kullanabilirsiniz:
s1 := student{name: "Evren"}
s1.mathGrade = 10
fmt.Print(s1.name, " adlı öğrencinin Matematik notu: ", s1.mathGrade)
Yukarıdaki örnekte görüldüğü gibi, bir struct tanımlanırken hangi değerlerinin atanacağı isteğe bağlıdır; tüm alanları belirtmediğiniz durumlarda Go varsayılan sıfır değerlerini atar ve herhangi bir derleme hatası almazsınız.
2. İç İçe Struct Kullanımı
Daha gerçekçi bir başka struct örneği verirsek:
type Coord struct {
X int
Y int
Z int
}
Örneğin Coord adında bir struct tanımlayarak X, Y, Z koordinatlarını tutabiliriz.
type Player struct {
name string
start Coord
}
Bu struct'ı oluşturduğumuz bir başka struct içerisinde dahi kullanabiliriz. Oluşturduğumuz bu struct'ları map, array veya slice değişkenleri içinde de tutmamız mümkündür:
students := [10]student{}
// Veya map içinde tutmak için:
students := make(map[int]student)
3. Struct ve Pointer Kullanımı
Son olarak, struct ve pointer tipinin birlikte kullanımına bir örnek verelim:
package main
import "fmt"
type student struct {
name string
mathGrade int
lithGrade int
}
func main() {
studentVar := student{name: "Evren", mathGrade: 10, lithGrade: 8}
fmt.Println(studentVar) // {Evren 10 8}
studentCopy := &studentVar
studentCopy.name = "Huseyin"
fmt.Println(studentVar) // {Huseyin 10 8}
}
Bu kodu çalıştırdığımızda şu çıktıyı alırız:
{Evren 10 8}
{Huseyin 10 8}
Pointer kullanarak studentCopy ile studentVar değişkenlerini eşitlemiş, struct'ımızı bellekte aynı adresi gösterecek şekilde değiştirilebilir (mutable) bir hâle getirmiş oluruz.
4. Struct Gömme (Struct Embedding)
Go'da struct'ların içine bir başka struct gömebilir, gömdüğünüz struct'ın tüm alanlarına yeni struct'ınız içerisinden doğrudan ulaşabilirsiniz. Struct'ların bu özelliği, nesne yönelimli programlama dillerindeki "kalıtım" ve "kompozisyon" yapılarına oldukça benzer. Microsoft Learn'deki örnekle inceleyelim:
package main
import "fmt"
type Person struct {
ID int
FirstName string
LastName string
Address string
}
type Employee struct {
Person
ManagerID int
}
type Contractor struct {
Person
CompanyID int
}
func (person *Person) nameTell() {
fmt.Println(person.FirstName)
}
func main() {
employee := Employee{
Person: Person{
FirstName: "John",
},
}
employee.LastName = "Doe"
fmt.Println(employee.FirstName) // John
employee.nameTell() // John
}
Yukarıdaki örnekte önce bir Person struct'ı oluşturduk ve bunu Contractor ve Employee struct'larının içine gömdük. İşin güzel tarafı, Person struct'ının tüm alanlarına Employee ve Contractor struct'ları içinden doğrudan ulaşabiliyoruz.
Employee içinde FirstName alanı doğrudan tanımlanmamış olmasına rağmen, employee.Person.FirstName şeklinde uzunca bir kullanım yerine doğrudan employee.FirstName kullanabiliyoruz. Benzer şekilde Person struct'ına özel tanımladığımız nameTell fonksiyonunu da doğrudan employee nesnesi üzerinde çağırabiliyoruz. Bu iki özellik, struct'ları Go'nun vazgeçilmez bir parçası haline getiriyor.
Struct'ları daha detaylı anlatmak için biraz gerçek dünya örneklerine ihtiyacımız var. Gelecekte yazacağım yazılarda bu örneklere yer vermeyi ümit ediyorum.
Bu Yazıda Yapılan Değişiklikler
- 11.05.2022: Yazı özeti düzenlendi.
- 21.06.2026: Derleme hatası veren değişken isimleri (
ogrenci->student), case-sensitive alan isimleri (mathgrade->mathGrade) ve gereksiz noktalı virgüller düzeltildi. CLI terminal çıktısındaki fazla eleman (baştaki sıfır) kaldırıldı. İmla hataları (birçok, doküman, fonksiyonu, değiştirilebilir vb.) giderildi, TL;DR özet ve karşılaştırma tablosu eklendi.
