[Golang] 변수가 어떤 interface의 매서드를 제공하는지 여부 확인하기

다음과 같은 타입이 있다고 치십시다.

type Boy int

func (b Boy) fight() {
	fmt.Println("Kaho-!")
}

func (b Boy) laugh() {
	fmt.Println("Kuwek-!")
}

type Girl float32

func (b Girl) laugh() {
	fmt.Println("kaka~")
}

또 다음과 같은 interface가 있다고 치자구요.

type Laughter interface {
	laugh()
}

type Fighter interface {
	fight()
}

이제 main 함수에서 Boy와 Girl 타입에 대한 객체를 정의할껀데요. 이 2개의 객체 변수가 Laughter, Fighter 인터페이스를 충족하는지의 여부를 검사하는 코드는 아래와 같습니다.

func main() {
	var b Boy
	var g Girl

	if _, ok := interface{}(b).(Laughter); ok {
		fmt.Println("Boy is laughter.")
	} else {
		fmt.Println("Boy is not laughter.")
	}

	if _, ok := interface{}(g).(Fighter); ok {
		fmt.Println("Girl is fighter.")
	} else {
		fmt.Println("Girl is not fighter.")
	}
}

그 결과는 예상하는 것처럼 아래와 같습니다.

Boy is laughter.
Girl is not fighter.

[Golang] 구조체 객체 생성

언어 Go는 필드를 하나의 개념으로 묶는 구조체 타입을 제공합니다. 아래는 (X, Y) 좌표를 나타내는 Point 타입을 나타냅니다.

type Point struct {
    x float64
    y float64
}

이 Point 타입을 객체로 만드는 방법은 너무….. 많아도 너무 마나. (마나? 히어로즈에서 제이나는 늘 마나가 부족하지..) 큭.. 여튼.. 많지만, 알고보면 일관성이 있어 이해가 어렵지 않은데요. 아래와 같은 다양한 방식을 지원합니다.

{
    var p Point
    p.x = 10.0
    p.y = 10.0
    fmt.Println(p)
}

{
    var p Point = Point{10.0, 10.0}
    fmt.Println(p)
}

{
    var p = Point{10.0, 10.0}
    fmt.Println(p)
}

{
    var p = Point{x: 10.0, y: 10.0}
    fmt.Println(p)
}

{
    var p *Point = new(Point)
    p.x = 10.0
    p.y = 10.0
    fmt.Println(p)
}

객체 생성 방식이 5개 정도 되는데요. 실행해 보면 다음과 같습니다.

{10 10}
{10 10}
{10 10}
{10 10}
&{10 10}

마지막 방식은 new를 통해 포인트 변수로 객체를 생성했습니다. 불행인지, 아니면 의도적인 것인지.. new를 통해 바로 구조체의 필드값을 지정할 수 없는데요. 이럴 때는 하나의 패턴으로 다음처럼 생성자 함수를 만들어 활용할 수 있습니다.

func NewPoint(x, y float64) *Point {
    return &Point{x, y}
}

위의 함수의 사용은 다음과 같습니다.

{
    var p = NewPoint(10.0, 10.0)
    fmt.Println(p)
}

실행 결과는 아래와 같습니다.

&{10 10}