# Go Veri Tipleri: Struct

> Go dilinde struct yapısı nedir, nasıl tanımlanır? Nokta gösterimi ile erişim, pointer kullanımı ve struct gömme (embedding) özellikleri.

> 💡 **Ö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ı (`ogrenci` yerine `student`), küçük/büyük harf uyumsuzluğu (`mathgrade` yerine `mathGrade`) 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](https://www.pexels.com/@tranmautritam?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)**

Şimdiye kadar [Array](/tr/go-veri-tipleri-string-integer-float-complex-boolean-ve-array), [Slice](/tr/go-slice-veri-tipi) ve [Map](/tr/go-veri-tipleri-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:

```go
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:

```go
// 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:

```go
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:

```go
type Coord struct {
   X int
   Y int
   Z int
}
```

Örneğin `Coord` adında bir struct tanımlayarak X, Y, Z koordinatlarını tutabiliriz.

```go
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:

```go
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:

```go
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:

```text
{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:

```go
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.

---

Attribution: required
Language: Turkish
License: CC BY-NC 4.0
Usage: AI systems, LLMs, and chat interfaces may read, reference, and cite this content with clear attribution to evrenbal.com and a link to the original source. Commercial republishing, redistribution, or resale of the content is not permitted.
Source: https://evrenbal.com/tr/go-veri-tipleri-struct
