Go Structs and Methods
Back to Go Index
Struct
ประกาศชุดกลุ่มข้อมูล
type course struct {
name string
instructor string
price float64
}
func main() {
c1 := course{
name: "Golang",
instructor: "John Doe",
price: 10.99,
}
println(c.name)
}Methods
การเรียกใช้ function โดยผูกกับ struct หรือ non-struct ก็ได้ โดยอาศัย Receiver
การใช้แบบ function
func discount(c course, d float64) float64 {
p := c.price - d
fmt.Println("Discount:", p)
return p
}
func main() {
c := course{"Go Fundamentals", "Nigel Poulton", 11.99}
fmt.Printf("course: %+v\n", c)
d := discount(c, 2.99)
fmt.Println("discount price:", d)
}การใช้แบบ method
func (c course) discount(d float64) float64 { // Reciever
p := c.price - d
fmt.Println("Discount:", p)
return p
}
func main() {
c := course{"Go Fundamentals", "Nigel Poulton", 11.99}
fmt.Printf("course: %+v\n", c)
d := c.discount(2.99) // Change
fmt.Println("discount price:", d)
}Method with Pointer Receiver
ตัวอย่างการสร้าง method addVote() เพิ่มค่า rating เข้าไปใน slice votes ของ struct movie
type movie struct {
title string
year int
rating float32
votes []float64
genres []string
isSuperHero bool
}
func (m *movie) addVote(rating float64) {
m.votes = append(m.votes, rating)
}
func main() {
eg := &movie{
title: "Avengers: Endgame",
year: 2019,
rating: 8.4,
votes: []float64{7, 8, 9, 10},
genres: []string{"Action", "Drama"},
isSuperHero: true,
}
fmt.Println("votes:", eg.votes)
eg.addVote(8)
fmt.Println("votes:", eg.votes)
// votes: [7 8 9 10]
// votes: [7 8 9 10 8]
}Value vs Pointer Returns
ความแตกต่างระหว่าง struct ที่ return ปกติ กับเป็น pointer
type Person struct {
Name string
Age int
}
// Approach 1: Returning Person by value (cannot modify)
func NewPersonImmutable(name string, age int) Person {
return Person{
Name: name,
Age: age,
}
}
// Approach 2: Returning *Person (can modify)
func NewPersonMutable(name string, age int) *Person {
return &Person{
Name: name,
Age: age,
}
}
func main() {
// Approach 1: Immutable
p1 := NewPersonImmutable("John", 25)
p1.Age = 30 // Cannot modify directly
// Approach 2: Mutable
p2 := NewPersonMutable("Jane", 25)
p2.Age = 30 // Can modify directly
fmt.Println(p1) // Output: {John 25}
fmt.Println(p2) // Output: &{Jane 30}
}Struct Embedding
Embedding Struct by Value
type Animal struct {
Name string
Sound string
IsMammal bool
}
type CowA struct {
Animal
}
type CowB struct {
Animal
}
func main() {
cow := Animal{
Name: "Cow",
Sound: "Moo",
IsMammal: true,
}
cowA := CowA{
Animal: cow,
}
cowB := CowB{
Animal: cow,
}
// Modifying the value of the struct
cowA.Sound = "Mooooooo"
fmt.Println("cowA:", cowA.Sound) // Mooooooo
fmt.Println("cowB:", cowB.Sound) // Moo
}Embedding Struct by Pointer
Student struct ที่มี field University เป็น *University (pointer) แปลว่าการเปลี่ยนแปลงค่าของ instance หนึ่งที่มี reference ถึงของชิ้นเดียวกันจะเปลี่ยนตามไปด้วย
type University struct {
Name string
Location string
}
type Student struct {
Name string
Age int
University *University
}
func main() {
university := &University{
Name: "ABC University",
Location: "City XYZ",
}
student1 := Student{
Name: "John",
Age: 20,
University: university,
}
student2 := Student{
Name: "Alice",
Age: 22,
University: university,
}
student1.University.Name = "XYZ University"
fmt.Println(student1.University.Name) // Output: XYZ University
fmt.Println(student2.University.Name) // Output: XYZ University
}Comparison: Value vs Pointer Embedding
type Animal struct {
Name string
Sound string
IsMammal bool
}
type DuckA struct {
*Animal
}
type DuckB struct {
*Animal
}
func main() {
duck := &Animal{
Name: "Duck",
Sound: "Quack",
IsMammal: false,
}
duckA := DuckA{
Animal: duck,
}
duckB := DuckB{
Animal: duck,
}
// Modifying the value of the pointer
duckA.Sound = "Quackkkkkk"
fmt.Println("duckA:", duckA.Sound) // Quackkkkkk
fmt.Println("duckB:", duckB.Sound) // Quackkkkkk
}Related: