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 birstring
yapısıdır.age
bir kişinin yaşını saklamak için kullanılan birint
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)
}
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)
}
- Rehber
- Önceki bölüm: Kontrol ifadeleri ve fonksiyonlar
- Sonraki bölüm: Object-oriented