Generic Programming & Type Assertion, Conversion in Golang

Sangdae Nam·2023년 8월 22일
0
post-thumbnail
  1. Golang을 다루다보면 강타입 언어라는 특성 때문에 type에 대한 처리를 해줄 때가 많다. 이때 type을 변형해서 작업해야할 때 type assertion이나 type conversion을 사용하게 된다. 사실 명시적으로 type assertion은 type 변형은 아니지만 interface로 들어오는 데이터에 대해 처리할 때 사용하게 된다. 자세한 것은 뒤에서 보도록 하자. 또한 Go에서는 1.18 버전부터 Generic Programming 이라는 것을 지원해주고 있다. 이것도 함께 보도록 하자.
  2. Generic Programming
    Generic Programming은 함수나 type이 여러 type에 대해 적용가능하도록 지원해주는 기능을 의미한다. 예를 들어 다음과 같은 함수가 있을 때는 이는 int에 대한 함수이므로 float로 들어오는 인자에 대해서는 처리가 불가능하다.
func add(a, b int) int {
    return a + b
}

하지만 다음과 같이 타입 파라미터(T)를 사용하면 여러 타입들에 대해 적용 가능한 함수를 만들 수 있다.

func add[T constraints.Integer | constraints.Float](a, b T) T {
    return a + b
}
  1. Type Assertion
    Type Assertion은 위에서 언급했듯이 타입 변환을 의미하지는 않는다. 하지만 interface로 들어온 데이터값에 대해 특정 타입으로 변환이 가능한지를 확인하고 가능하다면 변환해주는 역할을 할 수 있다.
func main() {
	var a interface{} = 1
    i := a // type interface
    i := a.(int) // type int
}

Golang에서 작업을 하다 보면 scalability 때문에 interface를 사용할 일이 자주 발생한다. 이것 때문에 본래 Golang의 취지와 다르게 Type Assertion을 하는 순간 코드가 보기 안좋게 되는 영향이 있으니, 귀찮다고 map[string]interface 와 같은 형태를 만드는 것을 지양하자.
3. Type Conversion
Type Conversion은 타입 변환을 의미한다. 간단하게 아래와 같이 명시적으로 형변환을 할 수 있다.

var i int 42
var f float64 = float64(i)

여기서 더 나아가서 type에 대한 것을 좀더 서비스에 맞게 명시하고 활용가능한 경우만 관리하고 싶다면 다음과 같은 활용도 가능하다.

package car
type Status string

const (
	StatusRunning Status = "running"
    StatusStopped Status = "stopped"
)

currentStatus := car.CurrentStatus // car.StatusRunning
currentStatusWithString := string(currentStatus) // "running"
car.Update().SetStatus(car.StatusStopped).SaveX()
currentStatusWithString = string(car.CurrentStatus) // "stopped"

다음과 같이 작성했을 때의 장점은 car의 status 값이 string type이지만 특정 status들에 대해서만 관리할 수 있게 된다는 것이다. 예를 들어 임의로 작성한, car의 status를 업데이트하는 SetStatus에는 파리미터로 car.Status 타입만 가능하게 하면 정해진 status들에 대해서만 업데이트가 가능하게 된다. 또한 나중에 필요할 때는 string type conversion을 통해 해당 값을 가져올 수도 있기 때문에 더 견고한 프로그램 작성이 가능해진다.

profile
AI+Backend

0개의 댓글