Go'da arayüzlerin verilerden çok işlevselliği tanımladığı gerçeğine aşinayım. Bir arabirime bir dizi yöntem koyarsınız, ancak bu arabirimi uygulayan herhangi bir şey için gerekli olabilecek alanları belirleyemezsiniz.
Örneğin:
// Interface
type Giver interface {
Give() int64
}
// One implementation
type FiveGiver struct {}
func (fg *FiveGiver) Give() int64 {
return 5
}
// Another implementation
type VarGiver struct {
number int64
}
func (vg *VarGiver) Give() int64 {
return vg.number
}
Şimdi arayüzü ve uygulamalarını kullanabiliriz:
// A function that uses the interface
func GetSomething(aGiver Giver) {
fmt.Println("The Giver gives: ", aGiver.Give())
}
// Bring it all together
func main() {
fg := &FiveGiver{}
vg := &VarGiver{3}
GetSomething(fg)
GetSomething(vg)
}
/*
Resulting output:
5
3
*/
Şimdi, yapamayacağın şey şöyle bir şey:
type Person interface {
Name string
Age int64
}
type Bob struct implements Person { // Not Go syntax!
...
}
func PrintName(aPerson Person) {
fmt.Println("Person's name is: ", aPerson.Name)
}
func main() {
b := &Bob{"Bob", 23}
PrintName(b)
}
Bununla birlikte, arayüzler ve gömülü yapılarla uğraştıktan sonra, bir modadan sonra bunu yapmanın bir yolunu keşfettim:
type PersonProvider interface {
GetPerson() *Person
}
type Person struct {
Name string
Age int64
}
func (p *Person) GetPerson() *Person {
return p
}
type Bob struct {
FavoriteNumber int64
Person
}
Gömülü yapı nedeniyle Bob, Person'un sahip olduğu her şeye sahiptir. Ayrıca PersonProvider arabirimini de uygular, böylece Bob'u bu arabirimi kullanmak için tasarlanmış işlevlere aktarabiliriz.
func DoBirthday(pp PersonProvider) {
pers := pp.GetPerson()
pers.Age += 1
}
func SayHi(pp PersonProvider) {
fmt.Printf("Hello, %v!\r", pp.GetPerson().Name)
}
func main() {
b := &Bob{
5,
Person{"Bob", 23},
}
DoBirthday(b)
SayHi(b)
fmt.Printf("You're %v years old now!", b.Age)
}
İşte yukarıdaki kodu gösteren bir Go Playground .
Bu yöntemi kullanarak davranıştan çok veriyi tanımlayan ve herhangi bir yapı tarafından sadece bu veriyi gömerek uygulanabilen bir arayüz oluşturabilirim. Bu gömülü verilerle açıkça etkileşime giren ve dış yapının doğasının farkında olmayan işlevler tanımlayabilirsiniz. Ve her şey derleme zamanında kontrol edilir! (Eğer pisliği, görebildiğim ki tek yolu, arayüz gömme olacağını PersonProvider
içinde Bob
yerine bir betondan daha, Person
. O derlemek ve zamanında başarısız olur.)
Şimdi, sorum şu: bu güzel bir numara mı yoksa farklı bir şekilde mi yapmalıyım?