Go
Objektorienterad programmering
Sök…
Anmärkningar
Gränssnittet kan inte implementeras med pekmottagare eftersom *User
är inte User
structs
Go stöder användardefinierade typer i form av strukturer och typalias. strukturer är sammansatta typer, de komponentuppgifter som utgör strukturtypen kallas fält . ett fält har en typ och ett namn som måste vara ungefär.
package main
type User struct {
ID uint64
FullName string
Email string
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
fmt.Println(user) // {1 Zelalem Mekonen [email protected]}
}
detta är också en juridisk syntax för att definiera strukturer
type User struct {
ID uint64
FullName, Email string
}
user := new(User)
user.ID = 1
user.FullName = "Zelalem Mekonen"
user.Email = "[email protected]"
Inbyggda strukturer
eftersom en struktur också är en datatyp, kan den användas som ett anonymt fält, den yttre strukturen kan direkt komma åt fälten för den inbäddade strukturen även om strukturen kom från ett annat paket. detta beteende ger ett sätt att härleda en del av eller hela din implementering från en annan typ eller en uppsättning typer.
package main
type Admin struct {
Username, Password string
}
type User struct {
ID uint64
FullName, Email string
Admin // embedded struct
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
fmt.Println(admin) // {zola supersecretpassword}
fmt.Println(user) // {1 Zelalem Mekonen [email protected] {zola supersecretpassword}}
fmt.Println(user.Username) // zola
fmt.Println(user.Password) // supersecretpassword
}
metoder
I Go är en metod
en funktion som verkar på en variabel av en viss typ, kallad mottagaren
mottagaren kan vara vad som helst, inte bara structs
utan även en function
, aliastyper för inbyggda typer som int
, string
, bool
kan ha en metod, ett undantag från denna regel är att interfaces
(diskuteras senare) inte kan ha metoder, eftersom en gränssnitt är en abstrakt definition och en metod är en implementering, försöker det generera ett sammanställningsfel.
genom att kombinera structs
och methods
du få en nära ekvivalent av en class
i objektorienterad programmering.
en metod i Go har följande signatur
func (name receiverType) methodName(paramterList) (returnList) {}
package main
type Admin struct {
Username, Password string
}
func (admin Admin) Delete() {
fmt.Println("Admin Deleted")
}
type User struct {
ID uint64
FullName, Email string
Admin
}
func (user User) SendEmail(email string) {
fmt.Printf("Email sent to: %s\n", user.Email)
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
user.SendEmail("Hello") // Email sent to: [email protected]
admin.Delete() // Admin Deleted
}
Pointer Vs Value-mottagare
mottagaren av en metod är vanligtvis en pekare av prestandaskäl eftersom vi inte skulle göra en kopia av instansen, som det skulle vara fallet i värdemottagaren, detta är särskilt sant om mottagartypen är en struktur. ett annat skäl att göra mottagartypen till en pekare skulle vara så vi kan ändra de data mottagaren pekar på.
en värdemottagare används för att undvika modifiering av data som mottagaren innehåller, en vaule-mottagare kan orsaka en prestationshit om mottagaren är en stor struktur.
package main
type User struct {
ID uint64
FullName, Email string
}
// We do no require any special syntax to access field because receiver is a pointer
func (user *User) SendEmail(email string) {
fmt.Printf("Sent email to: %s\n", user.Email)
}
// ChangeMail will modify the users email because the receiver type is a ponter
func (user *User) ChangeEmail(email string) {
user.Email = email;
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
user.SendEmail("Hello") // Sent email to: [email protected]
user.ChangeEmail("[email protected]")
fmt.Println(user.Email) // [email protected]
}
Gränssnitt och polymorfism
Gränssnitt ger ett sätt att specificera ett objekts beteende, om något kan göra detta kan det användas här. ett gränssnitt definierar en uppsättning metoder, men dessa metoder innehåller inte kod eftersom de är abstrakta eller genomförandet lämnas till användaren av gränssnittet. till skillnad från de flesta objektorienterade språk kan gränssnitt innehålla variabler i Go.
Polymorfism är kärnan i objektorienterad programmering: förmågan att behandla objekt av olika typer enhetligt så länge de följer samma gränssnitt. Go-gränssnitt ger denna kapacitet på ett mycket direkt och intuitivt sätt
package main
type Runner interface {
Run()
}
type Admin struct {
Username, Password string
}
func (admin Admin) Run() {
fmt.Println("Admin ==> Run()");
}
type User struct {
ID uint64
FullName, Email string
}
func (user User) Run() {
fmt.Println("User ==> Run()")
}
// RunnerExample takes any type that fullfils the Runner interface
func RunnerExample(r Runner) {
r.Run()
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
RunnerExample(admin)
RunnerExample(user)
}