🔥 타입 확장하기
Go 언어에서는 struct 타입뿐만 아니라 다른 타입에도 메서드를 선언할 수 있습니다. 아래 예제를 살펴보면 MyFloat
이라는 숫자 타입에 Abs
메서드를 선언한 것을 볼 수 있죠.
type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) }
go
MyFloat
은float64
타입을 기반으로 정의된 사용자 정의 타입입니다.Abs
메서드는MyFloat
타입의 리시버f
를 가집니다.- 메서드 내부에서는
f
의 값이 음수인 경우f
를 반환하고, 그 외의 경우에는f
를 그대로 반환합니다. - 반환 타입은
float64
로 지정되어 있네요.
이렇게 정의된 MyFloat
타입과 Abs
메서드는 아래와 같이 사용할 수 있습니다.
func main() { f := MyFloat(-math.Sqrt2) fmt.Println(f.Abs()) }
go
f
는MyFloat
타입의 변수로,math.Sqrt2
로 초기화되었습니다.f.Abs()
를 호출하면Abs
메서드가 실행되어f
의 절댓값을 반환하겠죠.- 반환된 값은
fmt.Println
을 통해 출력됩니다.
한 가지 주의할 점은, 메서드의 리시버 타입은 반드시 메서드와 같은 패키지 내에서 정의되어야 한다는 것입니다. 즉, 다른 패키지에서 정의된 타입이나 내장 타입(int
등)을 리시버로 사용할 수는 없어요.
그렇다면 서드파티 라이브러리 타입에 메서드를 추가하여 확장하고 싶을 때는 어떻게 해야 할까요? 이런 경우에는 typealias를 사용하면 됩니다.
예를 들어, time
패키지의 Time
타입에 Format
메서드를 추가하고 싶다고 해 보겠습니다.
package main import ( "fmt" "time" ) type MyTime time.Time func (t MyTime) Format(layout string) string { return time.Time(t).Format(layout) } func main() { t := MyTime(time.Now()) formatted := t.Format("2006-01-02 15:04:05") fmt.Println(formatted) }
go
MyTime
은time.Time
을 기반으로 정의된 typealias입니다.Format
메서드는MyTime
타입의 리시버t
를 가지며,layout
문자열을 인자로 받아 포맷팅된 시간 문자열을 반환합니다.- 메서드 내부에서는
t
를time.Time
타입으로 변환한 후, 기존의Format
메서드를 호출하여 결과를 반환하고 있네요.
이렇게 typealias를 사용하면 마치 time.Time
타입 자체에 Format
메서드를 추가한 것처럼 사용할 수 있습니다.
t := MyTime(time.Now()) formatted := t.Format("2006-01-02 15:04:05")
go
t
는MyTime
타입의 변수로,time.Now()
를 통해 현재 시간으로 초기화되었어요.t.Format("2006-01-02 15:04:05")
를 호출하면MyTime
에 정의된Format
메서드가 실행되겠죠.
이처럼 Go 언어에서는 struct 외에도 다양한 타입에 메서드를 추가할 수 있어서 코드의 가독성과 재사용성을 높일 수 있답니다. 또한 typealias를 활용하면 외부 패키지의 타입을 마치 자신의 타입인 것처럼 다룰 수 있어서 코드의 표현력도 좋아지죠.
메서드와 typealias를 잘 활용하면 코드를 더욱 간결하고 명확하게 작성할 수 있으니 적극적으로 활용해 보시는 것은 어떨까요?
위 다이어그램은 Go 언어에서 메서드와 typealias의 관계를 나타낸 것이랍니다. 메서드를 정의할 때는 리시버 타입이 반드시 같은 패키지 내에서 정의되어야 해요. 하지만 typealias를 사용하면 외부 패키지의 타입도 마치 자신의 타입인 것처럼 확장할 수 있죠.