[go] Go 언어에서 메소드의 변이성

Go 언어는 형식적인 서술이나 상속 개념을 가지고 있지 않습니다. 그렇기 때문에 Go 언어에서는 메소드의 변이성을 다른 방식으로 다룹니다.

메소드의 변이성은 메소드를 정의할 때, 해당 메소드를 호출할 수 있는 타입의 집합을 의미합니다. 이는 Go 언어에서 구현할 수 있는 인터페이스 타입의 변이성과도 관련이 있습니다.

메소드의 변이성 조건

Go 언어에서 메소드의 변이성은 다음과 같은 조건을 만족해야 합니다:

  1. 메소드의 수신자(receiver)와 호출자(caller)는 같은 패키지에 속해야 합니다.
  2. 메소드의 수신자는 타입 T이며, T는 구조체(struct)나 인터페이스(interface) 등 Go에서 정의된 타입이어야 합니다.
  3. 메소드를 정의하는 데에 사용된 이름은 접근 가능해야 합니다.

메소드의 수신자와 호출자가 같은 패키지에 속해야 하는 이유는 메소드의 코드가 호출 가능한 패키지에 있어야 하기 때문입니다. 또한, 메소드의 수신자 타입은 Go에서 정의된 타입이어야 합니다. 그렇기 때문에 메소드를 정의하는 구조체나 인터페이스 등의 타입이어야 합니다.

메소드의 변이성 예제

다음은 메소드의 변이성에 대한 예제입니다:

package main

import "fmt"

type Rectangle struct {
    width  int
    height int
}

func (r Rectangle) Area() int {
    return r.width * r.height
}

func (r Rectangle) Perimeter() int {
    return 2*r.width + 2*r.height
}

func main() {
    r := Rectangle{width: 10, height: 5}
    fmt.Println("넓이:", r.Area())
    fmt.Println("둘레:", r.Perimeter())
}

위의 예제 코드에서 Rectangle 구조체에 Area()Perimeter()라는 두 개의 메소드를 정의했습니다. 이러한 메소드들은 Rectangle 타입의 변수에서 호출할 수 있습니다.

인터페이스와 메소드의 변이성

Go 언어에서는 메소드와 인터페이스의 관계를 통해 변이성을 다룰 수 있습니다. 인터페이스 타입은 특정한 메소드 집합을 구현하는 타입을 나타내는데, 이때 메소드의 이름과 시그니처가 일치해야 합니다.

인터페이스 타입을 구현하는 메소드의 집합은 해당 인터페이스를 사용하는 모든 코드에서 호출 가능합니다. 이를 통해 Go 언어는 동적 디스패치(dynamic dispatch)를 제공할 수 있습니다.

인터페이스의 변이성 예제

다음은 인터페이스의 변이성에 대한 예제입니다:

package main

import "fmt"

type Shape interface {
    Area() int
    Perimeter() int
}

type Rectangle struct {
    width  int
    height int
}

func (r Rectangle) Area() int {
    return r.width * r.height
}

func (r Rectangle) Perimeter() int {
    return 2*r.width + 2*r.height
}

func main() {
    r := Rectangle{width: 10, height: 5}
    var s Shape
    s = r
    fmt.Println("넓이:", s.Area())
    fmt.Println("둘레:", s.Perimeter())
}

위의 예제 코드에서 Shape 인터페이스는 Area()Perimeter() 메소드를 정의하고 있습니다. Rectangle 구조체는 Shape 인터페이스를 구현하고 있으므로, Rectangle 타입의 변수를 Shape 타입으로 할당할 수 있습니다.

결론

Go 언어에서 메소드의 변이성은 메소드를 호출할 수 있는 타입의 조건을 나타냅니다. 메소드의 수신자와 호출자는 같은 패키지에 속하고, 메소드를 정의하는 데에 사용된 이름은 접근 가능해야 합니다. 인터페이스를 통해 메소드의 집합을 정의하고, 해당 인터페이스를 구현하는 타입은 해당 메소드들을 호출할 수 있습니다.

참고: The Go Programming Language Specification - Method Declarations