Go 메서드(Method)
Go에서 메서드는 특정 타입에 속하는 함수를 의미합니다. 메서드는 구조체(struct)와 같은 사용자 정의 타입에 대해 동작을 정의하는 데 사용됩니다. 메서드를 사용하면 특정 타입의 인스턴스와 관련된 작업을 수행하는 함수를 정의할 수 있습니다.
메서드 정의
메서드를 정의할 때는 함수 선언과 유사하지만, 함수명 앞에 리시버(receiver)를 명시합니다. 리시버는 메서드가 속하는 타입의 인스턴스를 가리킵니다.
값 리시버(Value Receiver)와 포인터 리시버(Pointer Receiver)
메서드는 값 리시버와 포인터 리시버를 사용할 수 있습니다. 값 리시버는 리시버의 복사본을 사용하고, 포인터 리시버는 리시버의 주소를 사용하여 메서드 내부에서 리시버의 값을 변경할 수 있습니다.
예제: 값 리시버를 사용하는 메서드
package main
import "fmt"
// Person 구조체 정의
type Person struct {
Name string
Age int
}
// Greet 메서드 정의 (값 리시버 사용)
func (p Person) Greet() string {
return "Hello, my name is " + p.Name
}
func main() {
p := Person{Name: "Alice", 30}
fmt.Println(p.Greet()) // 출력: Hello, my name is Alice
}
예제: 포인터 리시버를 사용하는 메서드
package main
import "fmt"
// Person 구조체 정의
type Person struct {
Name string
Age int
}
// UpdateName 메서드 정의 (포인터 리시버 사용)
func (p *Person) UpdateName(newName string) {
p.Name = newName
}
func main() {
p := Person{Name: "Alice", 30}
p.UpdateName("Bob")
fmt.Println(p.Name) // 출력: Bob
}
리시버 타입
리시버 타입은 메서드가 속하는 타입입니다. 리시버 타입은 구조체일 수도 있고, 사용자 정의 타입일 수도 있습니다. 리시버는 소문자로 시작하는 변수명으로 주로 사용되며, 일반적으로 타입 이름의 첫 글자를 소문자로 사용합니다.
type MyInt int
// Double 메서드 정의 (값 리시버 사용)
func (m MyInt) Double() int {
return int(m * 2)
}
메서드 호출
메서드는 구조체나 사용자 정의 타입의 인스턴스를 통해 호출됩니다. 메서드를 호출할 때는 점(.) 연산자를 사용합니다.
p := Person{Name: "Alice", 30}
fmt.Println(p.Greet()) // Greet 메서드 호출
m := MyInt(5)
fmt.Println(m.Double()) // Double 메서드 호출
메서드와 함수의 차이점
메서드는 특정 타입에 속하며, 해당 타입의 인스턴스를 통해 호출됩니다. 반면에 함수는 독립적으로 호출됩니다.
- 함수: 특정 타입에 속하지 않으며, 독립적으로 호출됩니다.
- 메서드: 특정 타입에 속하며, 해당 타입의 인스턴스를 통해 호출됩니다.
예제: 구조체와 메서드
다음은 구조체와 메서드를 사용하는 예제입니다.
package main
import "fmt"
// Circle 구조체 정의
type Circle struct {
Radius float64
}
// Area 메서드 정의 (값 리시버 사용)
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
// Scale 메서드 정의 (포인터 리시버 사용)
func (c *Circle) Scale(factor float64) {
c.Radius *= factor
}
func main() {
c := Circle{Radius: 5}
fmt.Println("Original Radius:", c.Radius) // 출력: Original Radius: 5
fmt.Println("Area:", c.Area()) // 출력: Area: 78.5
c.Scale(2)
fmt.Println("Scaled Radius:", c.Radius) // 출력: Scaled Radius: 10
fmt.Println("Area:", c.Area()) // 출력: Area: 314
}
위 예제에서 Circle 구조체는 Area와 Scale이라는 두 개의 메서드를 가지고 있습니다. Area 메서드는 값 리시버를 사용하여 원의 면적을 계산하고, Scale 메서드는 포인터 리시버를 사용하여 원의 반지름을 변경합니다.
요약
- 메서드 정의: 메서드는 함수와 유사하게 정의되지만, 함수명 앞에 리시버를 명시합니다.
- 값 리시버: 리시버의 복사본을 사용합니다. 리시버의 값을 변경하지 않습니다.
- 포인터 리시버: 리시버의 주소를 사용하여 메서드 내부에서 리시버의 값을 변경할 수 있습니다.
- 메서드 호출: 구조체나 사용자 정의 타입의 인스턴스를 통해 점(.) 연산자로 호출합니다.
Go에서 메서드는 특정 타입과 관련된 동작을 정의하고, 데이터와 동작을 함께 묶어 객체지향적인 코드를 작성할 수 있게 해줍니다.
GIT : https://github.com/kkaok/study-golang/tree/master/src/example/method
출처 : chatGPT