잠시만 기다려 주세요

     '입만 나불거리고 행동하지 않는 야당을 규탄한다.'
전체검색 :  
이번주 로또 및 연금번호 발생!!   |  HOME   |  여기는?   |  바다물때표   |  알림 (16)  |  여러가지 팁 (1059)  |  추천 및 재미 (156)  |  자료실 (22)  |  
시사, 이슈, 칼럼, 평론, 비평 (613)  |  끄적거림 (136)  |  문예 창작 (716)  |  바람 따라 (75)  |  시나리오 (760)  |  드라마 대본 (248)  |  
살인!


    golang

golang - golang으로 만나보는 Duck Typing
이 름 : 바다아이   |   조회수 : 12755         짧은 주소 : https://www.bada-ie.com/su/?181591813298
Duck Typing ( 이하 덕 타이핑) 이란 방식이 세상에 알려진지는 상당한 시간이 지났다.  이미 덕 타이핑을 이해하고 덕 타이핑 동작 방식을 수용한 Program Language 를 도입하여 사용하는 이들도 있지만 아직까지 덕 타이핑이 무엇인지 모르는 분들이 주위에 상당하기에 이 글을 통해서  덕 타이핑에 대한 개념과 Golang 기반 Example Code를 작성하여 이해를 돕고자 합니다.




 

덕 타이핑 이란?

덕 타이핑이란 용어는 2000년 파이선 뉴스그룹에 Alex Martelli 가 올린 다음의 글이 시초가 되었다.
“In other words, don’t check whether it IS-a duck: check whether it QUACKS-like-a duck, WALKS-like-a duck, etc, etc, depending on exactly what subset of duck-like behaviour you need to play your language-games with.”
요약하자면
“그게 오리인지 검사하지 말고,  당신이 오리의 무슨 행동이 필요한지에 따라서 오리처럼 우는지, 오리처럼 걷는지 기타 등등… 적절한 행동을 오리처럼 하는지 검사 하세요”
즉 사람이라도 오리처럼 꽥꽥울고, 오리처럼 뒤뚱뒤뚱 걸으면 그건 사람이 아니라 오리라고 판단 하겠다는 말이다.

덕 타이핑은  이게 전부다!
진짜 이게 전부입니다!
사실 위의 인용구는 덕 테스트의 개념이고 덕 타이핑은 덕 테스트가 방식으로 진화된것이라고 할 수 있다.  덕 테스트는 동적 언어의 다형성(polymorphism)지원&구현에 관한 논쟁에서 자주 언급되어져 왔었고 그렇다면 정적, 동적 언어는 무엇인지에 대해 안 짚어 볼 수 가 없다.
 

Static, Dynamic Language

우선 정적(Static), 동적(Dynamic) 언어의 특징과 차이점에 대해 간략하게 정리해 보면.

정적 언어

  • 변수 또는 함수의 Type을 미리 지정해야 함.
  • 컴파일 시점에 Type Check가 가능.

동적 언어

  • 변수 또는 함수의 Type을 지정하지 않고 사용할 수 있음.
  • Type Check는 runtime시점에서만 알 수 있음.
  • Type지정이 안되어 있어 소스 분석 어려움.

정적, 동적 언어의 가장 큰 차이점은 Type정보를 지정해야 하냐? 아니냐? 로 볼 수 있다.
(요즘들어서는 전통적인 정적 언어들도 일부 동적 언어의 기능을 도입한 경우도 볼 수 있음)
다음 pseudo code는 정적,동적 언어의 Type관련 차이점을 보여주고 있다.


a  = 9
b = "9"
c = concatenate(  str(a),  b)
d = add(a,  int(b)  )


a  = 9
b = "9"
c = concatenate(a, b)  // produces "99"
d = add(a, b)          // produces 18



동적 언어는 이런 코딩 간결함 덕분에 초기 Learning Curve가 크지 않아 Business가 고착화되지 않아 잦은 기능변경이 필요한 Startup 에서 많이들 선택하고 있고 이를 동적 언어의 매력이라 말하기도 한다.

하지만 이런 동적 언어도 한가지 문제점이 있는데 컴파일 과정이 없다보니 간단한 문법 오류 조차도 Runtime시점에 나타난 다는것이다.

비단 문법오류가 아니더라도 Runtime시점에 기대했던 객체가 다른객체로 전달될 가능성이 있기 때문에 그로 인해 예상치 못한 실행결과를 나타내기도 한다. 물론 이런 문제점은 테스트 코드로 커버 할 수 있으며 테스트 커버리지율이 높아 질 수록 테스트 단계에서 발견되는 오류가 많아지고 이를 해결하면서 더욱더 견고한  Program이 될 수 있고 더불어 테스트 코드를 작성하는 좋은 습관을 만들어 갈수도 있다. 하지만 이는 어디까지나 보완책일뿐 동적언어가 가지고는 이 문제점에서 자유로워 질 순 없다.
이 처럼 정적, 동적언어는 서로 일장일단이 존재하며 동적 언어로 시작한 후 Business가 고착화 되면서 정적 언어로 변경한 Startup 도 심심치 않게 볼 수 있다.
그렇다면 동적 언어의 개발속도와 편리성, 컴파일 기반의 정적 언어의 안정감을 둘 다 가질 수는 없는 것인가?



type Duck interface {
    Quack() string // 쾍쾍 거리는 동작
    Walk() string// 걷는 동작
}


Duck 인터페이스를 구현한 Swan 구조체


type Swan struct {
}

func (s Swan) Quack() string {
    return "고니 울름소리"
}

func (s Swan) Walk() string {
    return "고니 걷는 모습"
}


Duck 인터페이스를 구현한 Chicken 구조체


type Chicken struct {
}

func (c Chicken) Quack() string {
    return "닭 울름소리"
}

func (c Chicken) Walk() string {
    return "닭 걷는 모습"
}
 

위 Swan, Chicken 구조체를 보면 Duck 인터페이스를 구현한다는 명시적 keyword가 전혀 보이지 않는다. 그저 Duck 인터페이스의 동작을 구현한것으로 이들은 Duck 인터페이스 타입으로 사용될 수 있는것이다.

다음 예제는 Duck 인터페이스를 구현 했다면 “깜짝 놀랬을 때 울고 난 후 걷는다(도망) 간다” 가 정상적으로 동작하는지를 보는 예이다.

(Go에서 함수(function)와 메소드(Method)는 엄연히 틀린 개념이다. 우리가 일반적으로 알고 있는 함수의 개념을 함수라고 불려지고 메소드는 구조체에 추가시킬 동작을 일컽는 개념 이므로 오해하면 안된다.)


//깜짝 놀랬을 때 울고 난 후 걷는다(도망) 간다
func Scare(duck Duck) {
    // Duck의 동작을 구현한 어떤 객체라도 argument로 전달 될 수 있다.

    fmt.Println(duck.Quack())
    fmt.Println(duck.Walk())
}

func main() {
    var swan Duck = Swan{}
    Scare(swan)

    var chicken Duck = Chicken{}
    Scare(chicken)

}


실행하면 아래와 같은 결과를 확인 할 수 있다.




자 그렇다면 Duck 인터페이스를 구현하지 않은 경우는 어떻게 될까?


func Scare(duck Duck) {
    // Duck의 동작을 구현한 어떤 객체라도 argument로 전달 될 수 있다.

    fmt.Println(duck.Quack())
    fmt.Println(duck.Walk())
}

type Human struct {

}

func main() {
    var swan Duck = Swan{}
    Scare(swan)

    fmt.Println("-----------------------------------")

    var chicken Duck = Chicken{}
    Scare(chicken)

    fmt.Println("-----------------------------------"

    var human Duck = Human{} // 컴파일 에러 발생.

    Scare(human)
}
 

일반적인 동적 언어라면 실행시점에서 에러가 발생하겠지만 Go는 컴파일 타임이 존재 하므로 컴파일 에러가 발생해 실행조차 할 수 없다.

많은 컴파일 언어에서는 특정 라이브러리나 프레임웤과 호환되는 객체를 만들려면 특정 인터페이스를 구현하거나 클래스를 상속받아 구현 하는게 일반적이고 이렇게 생성된 클래스는 특정 라이브러리나 프레임웤과 강한 연결고리가 형성 되기에 변경이나 확장에 용이 하지 않다.

반면  Go에선 덕 타이핑 방식으로 작동하는 인터페이스를 통해 위 예제와 같은 다형성을 지원하고 있고  이런 특징덕에 정적 Type언어임에도 불구하고 모듈간 결합도가 낮고 확장하기 쉬운 이점을 가지고 있다.

마치며

지금까지 덕 타이핑이라는 주제로 정적 동적 언어의 특징에 대해 살펴봤고 Go에서 덕 타이핑이 어떤식으로 구현되는지 매우 심플하게 알아봤다. 덕 타이핑은 프로그래머들 사이에 상당히 논란이 많은 개념이다.  누구는 덕 타이핑 개념은 “오리의 동작을 잘 구현 했을꺼야?” 라는 믿음을 바탕으로 하기에 프로그래머의 실수에 의한 오류가 항상 존재함을 Language측면에서 강제 해야한다는 의견도 있고, 누구는 그런 제약이 존재함으로써 복잡도가 증가하고 유지보수 비용이 많이 든다는 의견도 있고, 누구는 그런 자유도 때문에 코딩이 재미있고 생산성이 향상되고 확장이 용이하다고 말하는 사람도 있다.
정답은 없다!
스스로 만들고자 하는 목적물에 이런 장,단점이 적절 한가를 판단하고 사용하면  될거라고 본다.
다만 본인에게 익숙한 어떤 개념이나 기술에 너무 집착하거나 얽매이지 않았으면 하는 바램을 가지며 글을 마친다.


출처 : http://www.popit.kr/golang%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%82%98%EB%B3%B4%EB%8A%94-duck-typing/
 

| |





      1 page / 6 page
번 호 카테고리 제 목 이름 조회수
179 golang golang , ... 바다아이 1825
178 golang golang , map . 바다아이 1407
177 golang Golang (, , data ) , ... 바다아이 1466
176 golang golang sort ... 바다아이 1706
175 golang golang html.EscapeString html.UnescapeString input value ... 바다아이 1798
174 golang golang go.mod go.sum . GOPATH SRC not module, 1.16 . 바다아이 5097
173 golang go 1.16 ... is not in GOROOT.. GOPATH .... . 바다아이 6013
172 golang , String Formatting 바다아이 7646
171 golang rand.Intn , random, , . 바다아이 7115
170 golang golang ... 바다아이 10253
169 golang golang gopath, goroot .. golang 바다아이 7759
168 golang golang ... Force download file example 바다아이 9566
167 golang golang , , cpu, memory, disk 바다아이 10848
166 golang golang , ... GOOS, GOARCH 바다아이 8605
165 golang golang checkbox ... 바다아이 8372
164 golang golang , , http .... 바다아이 8129
163 golang golang nil , nil , nil ... 바다아이 8478
162 golang 2 golang, go , .... golang .... 바다아이 11356
161 golang golang postgresql, mysql, mariadb ... ` Grave () .. .. 바다아이 8672
160 golang golang postgresql mysql, mariadb scan , null .. 바다아이 8815
159 golang golang , iconv 바다아이 11621
158 golang golang quote escape, unquote 바다아이 9068
157 golang golang , http errorLog , , ... 바다아이 9137
156 golang golang interface , 바다아이 8584
155 golang golang struct .... 바다아이 9317
154 golang golang map map , 바다아이 8777
153 golang golang map .... .... 바다아이 8306
152 golang golang slice copy 바다아이 8428
151 golang golang goto 바다아이 9315
150 golang golang slice sort , int, string, float64 바다아이 8790
| |









Copyright ⓒ 2001.12. bada-ie.com. All rights reserved.
이 사이트는 리눅스에서 firefox 기준으로 작성되었습니다. 기타 브라우저에서는 다르게 보일 수 있습니다.
[ Ubuntu + GoLang + PostgreSQL + Mariadb ]
서버위치 : 오라클 클라우드 춘천  실행시간 : 0.06548
to webmaster... gogo sea. gogo sea.