Methods
Method adalah fungsi yang terikat dengan tipe data tertentu. Di Go, kita bisa menambahkan method ke tipe data apapun yang didefinisikan dalam package yang sama.
Contoh Masalah
Bagaimana cara:
- Menambahkan behavior ke tipe data
- Membuat object-oriented like programming
- Mengorganisir fungsi yang berhubungan
Penyelesaian
package main
import (
"fmt"
"math"
)
// 1. Struct dengan methods
type Rectangle struct {
Width float64
Height float64
}
// Method dengan value receiver
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Method dengan pointer receiver
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
// 2. Method untuk tipe data dasar
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
// 3. Interface implementation dengan method
type Shape interface {
Area() float64
Perimeter() float64
}
// Implementasi interface untuk Rectangle
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
// Circle dengan method
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.Radius
}
// 4. Method chaining
type StringBuilder struct {
str string
}
func (sb *StringBuilder) Append(s string) *StringBuilder {
sb.str += s
return sb
}
func (sb *StringBuilder) AppendLine(s string) *StringBuilder {
sb.str += s + "\n"
return sb
}
func (sb StringBuilder) String() string {
return sb.str
}
func main() {
// Contoh 1: Rectangle methods
rect := Rectangle{Width: 10, Height: 5}
fmt.Printf("Rectangle: %+v\n", rect)
fmt.Printf("Area: %.2f\n", rect.Area())
fmt.Printf("Perimeter: %.2f\n", rect.Perimeter())
// Menggunakan pointer method
rect.Scale(2)
fmt.Printf("\nSetelah scaling: %+v\n", rect)
fmt.Printf("Area baru: %.2f\n", rect.Area())
// Contoh 2: Method pada tipe data dasar
f := MyFloat(-42)
fmt.Printf("\nAbsolute value: %.2f\n", f.Abs())
// Contoh 3: Interface dan method
var shapes []Shape
shapes = append(shapes, Rectangle{Width: 3, Height: 4})
shapes = append(shapes, Circle{Radius: 5})
fmt.Printf("\nCalculating areas:\n")
for _, shape := range shapes {
fmt.Printf("Area: %.2f\n", shape.Area())
fmt.Printf("Perimeter: %.2f\n", shape.Perimeter())
}
// Contoh 4: Method chaining
sb := &StringBuilder{}
result := sb.Append("Hello").
AppendLine(" World!").
Append("How ").
AppendLine("are you?").
String()
fmt.Printf("\nStringBuilder result:\n%s", result)
// Contoh 5: Value vs Pointer receiver
r1 := Rectangle{Width: 2, Height: 3}
r2 := r1 // Copy value
r1.Scale(2) // Only affects r1
fmt.Printf("\nValue vs Pointer receiver:\n")
fmt.Printf("r1: %+v\n", r1)
fmt.Printf("r2: %+v\n", r2)
}
Penjelasan Kode
Method Declaration
- Fungsi dengan receiver
- Value vs pointer receiver
- Dapat ditambahkan ke tipe apapun
Receiver Types
- Value receiver: mendapat copy
- Pointer receiver: dapat mengubah nilai
- Pilih sesuai kebutuhan
Method vs Function
- Method terikat dengan tipe
- Lebih object-oriented
- Lebih mudah dibaca
Output
Rectangle: {Width:10 Height:5}
Area: 50.00
Perimeter: 30.00
Setelah scaling: {Width:20 Height:10}
Area baru: 200.00
Absolute value: 42.00
Calculating areas:
Area: 12.00
Perimeter: 14.00
Area: 78.54
Perimeter: 31.42
StringBuilder result:
Hello World!
How are you?
Value vs Pointer receiver:
r1: {Width:4 Height:6}
r2: {Width:2 Height:3}
Tips
- Gunakan pointer receiver untuk mengubah state
- Gunakan value receiver untuk operasi read-only
- Konsisten dalam penggunaan receiver type
- Method membuat code lebih modular
- Manfaatkan method chaining untuk fluent interface