$Id: 281
$SOId: 8801
@draft
Go is not an object oriented programming language. If you're familiar with other OO languages (Python, C++, Java etc.) you'll notice some similarities but you should also understand differences.
Structs are similar to classes in that you can define methods on them to encapsulate logic related to a type:
type Person struct {
firstName string
lastName string
}
func (p *Person) FullName() string {
if p.firstName != "" && p.lastName != "" {
return p.firstName + " " + p.lastName
}
return p.firstName + p.lastName
}
u := &Person{firstName: "Jon", lastName: "Snow"}
fmt.Printf("Full name: %s\\n", u.FullName())
We defined FullName()
method on type *Person
.
Variable p
that is a target of the method is called a receiver.
Idiomatic Go style is to use a short name for the receiver based on type name.
A bad Go style is to call the receiver this
.
Unlike most languages, you can also implement methods on all types, not just structs.
type myInt int
func (i myInt) String() string {
return strconv.Atoi(int(i))
}
myInt := 5
fmt.Printf("myInt: %s\\n", myInt.String())
You can only implement methods on your own types (i.e. method must be defined in the same package as the type). That's why we had to introduce myInt
alias for int
type.
type BritishPerson struct {
Person
isKnight bool
}
type (p *BritishPerson) IsKnight() bool {
return p.isKnight
}
p := &BritishPerson{Person: {firstName:"Tim", lastName: "Berners-Lee"}, isKnight: true}
if p.IsKnight() {
fmt.Printf("%s is a knight\\n", p.FullName())
}
BritishPerson
embeds Person
anonymously and therefore you can call all Person
methods on instances of BritishPerson
.
Embedding allows to share common functionality among multiple structs.