Skip to content

Latest commit

 

History

History
214 lines (170 loc) · 5.97 KB

File metadata and controls

214 lines (170 loc) · 5.97 KB

2.4 struct

struct

Diğer programlama dillerinde olduğu gibi, Go'daki diğer özelliklerin veya alanların yeni tür konteynerlerini tanımlayabiliriz. Örneğin, bir kişiyi temsil etmek için alan adı ve yaşıyla birlikte kişi adında bir tür oluşturabiliriz. Bu türleri struct olarak adlandırıyoruz.

type kisi struct {
	name string
	age int
}

Struct yapısını tanımlamanın ne kadar kolay olduğuna bir bakın!

İki alan var.

  • name bir kişinin ismini saklamak için kullanılan bir string yapısıdır.
  • age bir kişinin yaşını saklamak için kullanılan bir int yapısıdır.

Nasıl kullanıldığını görelim.

type person struct {
	name string
	age int
}

var P person  // p person tipi

P.name = "Astaxie"  // p'nin `name` alanına "Astaxie" atayın
P.age = 25  // p'nin `age` alanına 25 atayın
fmt.Printf("The person's name is %s\n", P.name)  // p'nin `name` alanını ekrana yazdırın

Bir struct'ı başlatmanın üç yolu daha var.

  • İlk değerleri siparişe göre atama
P := person{"Tom", 25}
  • Struct'ı sırasız başlatmak için field:value biçimini kullanın
P := person{age:24, name:"Bob"}
  • Anonim bir struct tanımladıktan sonra başlatın
P := struct{name string; age int}{"Amy",18}

Tamamlanmış bir örnek görelim.

package main

import "fmt"

// yeni bir tür tanımlama
type person struct {
	name string
	age  int
}

// struct değere göre geçildi
// iki insanın yaşını karşılaştırır, sonra yaşlı olanı ve yaş farkını getirir.
func Older(p1, p2 person) (person, int) {
	if p1.age > p2.age {
		return p1, p1.age - p2.age
	}
	return p2, p2.age - p1.age
}

func main() {
	var tom person

	tom.name, tom.age = "Tom", 18
	bob := person{age: 25, name: "Bob"}
	paul := person{"Paul", 43}

	tb_Older, tb_diff := Older(tom, bob)
	tp_Older, tp_diff := Older(tom, paul)
	bp_Older, bp_diff := Older(bob, paul)

	fmt.Printf("Of %s and %s, %s is older by %d years\n", tom.name, bob.name, tb_Older.name, tb_diff)
	fmt.Printf("Of %s and %s, %s is older by %d years\n", tom.name, paul.name, tp_Older.name, tp_diff)
	fmt.Printf("Of %s and %s, %s is older by %d years\n", bob.name, paul.name, bp_Older.name, bp_diff)
}

yapıya gömülü alanlar

Daha önce alan adlarıyla ve türleriyle bir struct tanımlamayı öğrendik. Aslında Go alanları adları olmayan ancak türleriyle destekler. Bu gömülü alanları diyoruz.

Gömülü alan bir struct olduğunda, o struct'taki tüm alanlar gömülü olduğu struct içindeki alanlar olacaktır.

Bir örnek görelim.

package main

import "fmt"

type Human struct {
	name   string
	age    int
	weight int
}

type Student struct {
	Human     // gömülü alan Studen struct'ı Human'ın sahip olduğu tüm alanları içerir.
	specialty string
}

func main() {
	// öğrenciyi somutlaştırın ve başlatın.
	mark := Student{Human{"Mark", 25, 120}, "Computer Science"}

	// erişim alanları
	fmt.Println("His name is ", mark.name)
	fmt.Println("His age is ", mark.age)
	fmt.Println("His weight is ", mark.weight)
	fmt.Println("His specialty is ", mark.specialty)

	// mark'ın uzmanlık alanını değiştirin
	mark.specialty = "AI"
	fmt.Println("Mark changed his specialty")
	fmt.Println("His specialty is ", mark.specialty)

	fmt.Println("Mark become old. He is not an athlete anymore")
	mark.age = 46
	mark.weight += 60
	fmt.Println("His age is", mark.age)
	fmt.Println("His weight is", mark.weight)
}

Şekil 2.7 Student'a ve Human'a Gömme

Human'da olduğu gibi Student'taki age ve name alanlarına erişebildiğimizi görüyoruz. Bu gömülü alanların çalışma şeklidir. Çok havalı değil mi? Bekle, daha havalı bir şey var! Bu gömülü alanda Human'a erişmek için Student bile kullanabilirsin!

mark.Human = Human{"Marcus", 55, 220}
mark.Human.age -= 1

Go'daki tüm türler gömülü alanlar olarak kullanılabilir.

package main

import "fmt"

type Skills []string

type Human struct {
	name   string
	age    int
	weight int
}

type Student struct {
	Human     // gömülü alan olarak struct
	Skills    // gömülü alan olarak string dilimi
	int       // gömülü alan olarak yerleşik tür
	specialty string
}

func main() {
	// Student Jane'i başlat
	jane := Student{Human: Human{"Jane", 35, 100}, specialty: "Biology"}
	// erişim alanı
	fmt.Println("Her name is ", jane.name)
	fmt.Println("Her age is ", jane.age)
	fmt.Println("Her weight is ", jane.weight)
	fmt.Println("Her specialty is ", jane.specialty)
	// beceri alanının değerini değiştir
	jane.Skills = []string{"anatomy"}
	fmt.Println("Her skills are ", jane.Skills)
	fmt.Println("She acquired two new ones ")
	jane.Skills = append(jane.Skills, "physics", "golang")
	fmt.Println("Her skills now are ", jane.Skills)
	// gömülü alanı değiştir
	jane.int = 3
	fmt.Println("Her preferred number is ", jane.int)
}

Yukarıdaki örnekte, tüm türlerin gömülü alanlar olabileceğini görebilir ve üzerinde çalışmak için işlevleri kullanabiliriz.

Ancak bir sorun daha var. Human'ın phone adında bir alanı varsa ve Student'ta aynı adı taşıyan bir alan varsa ne yapmalıyız?

Hadi çözmek için çok basit bir yol kullan. Dış alanlar daha yüksek erişim seviyelerine sahip olur, yani “student.phone” 'a eriştiğinizde, Human struct'ında değil Student olarak telefon denilen alanı elde ederiz. Bu özellik basitçe alan aşırı yüklemesi olarak görülebilir.

package main

import "fmt"

type Human struct {
	name  string
	age   int
	phone string // Human bir telefon alanına sahip
}

type Employee struct {
	Human
	specialty string
	phone     string // çalışan telefon
}

func main() {
	Bob := Employee{Human{"Bob", 34, "777-444-XXXX"}, "Designer", "333-222"}

	fmt.Println("Bob's work phone is:", Bob.phone)
	fmt.Println("Bob's personal phone is:", Bob.Human.phone)
}

Links