일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- CORDA
- Hyperledger fabric gossip protocol
- 하이퍼레저 패브릭
- 하이브리드앱
- hyperledger fabric
- 파이썬 데이터분석
- 엔터프라이즈 블록체인
- 이더리움
- Golang
- Play2
- 파이썬
- 주키퍼
- 플레이프레임워크
- akka 강좌
- play 강좌
- 스칼라 동시성
- 그라파나
- 안드로이드 웹뷰
- play2 강좌
- Adapter 패턴
- 스칼라 강좌
- 파이썬 머신러닝
- 스칼라
- 블록체인
- Actor
- Play2 로 웹 개발
- 스위프트
- 파이썬 강좌
- 파이썬 동시성
- Akka
- Today
- Total
HAMA 블로그
스칼라 강좌 (42) 고급 타입 다루기 - F-bounded polymorphism / recursive types 본문
스칼라 강좌 (42) 고급 타입 다루기 - F-bounded polymorphism / recursive types
[하마] 이승현 (wowlsh93@gmail.com) 2017. 3. 26. 13:32F-bounded polymorphism / recursive types
번역:http://blog.originate.com/blog/2014/02/27/types-inside-types-in-scala/
지금까지 이런 타입 시그니처 본 적이 있어? (역주: 난 얼마전에 봤다...당황 많이 했어 ;;)
처음 이런 모습을 보았을때, "머야 이 퐝당한 코드" 같은 생각이 드는건 어쩌면 당연해. 그리고 이것에 대해 알아 보기 위해 구글링등을 하기 시작 했을테고, 결국 이 블로그를 찾아 왔을 지도? 그렇다면 잘 찾아 왔네 친구~ ^^
좋아, 저 헤괴망측한것은 도대체 뭘까? 보통 우린 trait T[U] 이렇게 써 왔잖아?
(역주: T[U <: T[U]] 라니? U 타입이긴 한데 T[U] 의 하위 타입이라고? U 가 두군데 저렇게 쓰여도 됨? 미리 답을 얘기하면 여기서 U 타입은 T[U] 를 상속받은 타입만으로 강제 되는 거야. )
알고보면 매우 간단하니깐 겁먹지 말고 , 간단한 예를 통해서 이해해 보자고.
자 출발!
우리에게 매우 익숙한 CRUD 에 대한 코드를 짜 볼거야. 아래와 같이 case class 를 이용해서 간단하게
사과랑 새라는 두개의 클래스가 있는데, 잘 보면 두 클래스가 하는 역할이 너무 비슷하잖아? 중복되는 느낌도 들고~ 앞으로 비슷한 클래스를 작성 할때 저 코드를 또 타이핑 해야할 것을 생각하면 한숨이 나오지..그렇다면 리팩토링의 화신인 우리가 해야할 것은 무엇일까?
그래 인터페이스로 끌어 올리는거야. 스칼라에서는 trait 라는 쿨한 녀석이 있잖아?
앗..망할 ㅋㅋ trait 의 메소드 시그니처 보면 좀 문제가 있네. 우리가 원한것은 Apple 이면 Apple 에 대해 작업 하길 원하는데 이 코드라면 그냥 CrudEntity 를 리턴하잖아;;
CrudEntity 트레잇에 좀 더 명확한 타입을 추가해보자..
좋아. 우리가 생각한건 이런거잖아. ( 대부분 여기 까지 작업하고 종료를 하겠지 ?)
하지만 좀 만 더 생각해보면 살짝 문제가 있어. 무엇일까?
문제점은 바로 누군가 CrudEntity_2 를 이렇게 정의하면 생겨..
웁스~ 위에 코드에선 CrudEntity_2[E] 의 E타입에 제약이 없어서, 아무거나 넣어도 컴파일러가 불평불만을 안하잖아? 우리가 강력한 타입시스템을 사용하는 이유가 조금 의미 없어졌네.. Orange 만 넣도록 해야하는데 말이야.
그래 무조건 CrudEntity_2[E] 에서 E 에는 CrudEntity_2 를 상속한 녀석만 들어가도록 제약을 걸고 싶지?
짜잔~~ 이때 등장하는것이 우리가 처음 퐝당해 했던 저 코드야~! 아래를 보라고.
아주 훌륭해 졌어. 이제 E 타입은 무조건 해당 subtype 만 들어 갈 수 있어. 응? 해당 subtype?? 이라고?? 그럼 아래처럼도 되겠네? 이건 우리가 원한게 아니잖아?
그럼 이건 어떻게 해결 해야 할까? 이 경우에 우리는 self type 을 써서 해결 할 수 있어.
이제 마지막이야..다 왔어. 친구~ CrudEntity
는 다음과 같이 정의면 모든게 해결이야.
(역주: self 대신 this 로 해도되고, foo 로 해도 됩니다.)
self: E =>
를 추가하면 CrudEntity
[E] 를 상속받은 객체는 반드시 자신의 타입인 E
가 되야해.
Orange
는 Apple
타입이 아니라는것을 컴파일러가 확실히 제약해주지.
이 정도는 해야 우리가 원하는 안전하고 확실한 강력한 타입을 가지는 코드라고 할 수 있지 않을까?
그럼 빠잉~
'Scala' 카테고리의 다른 글
스칼라 강의 (44) - 리플렉션 (0) | 2017.11.06 |
---|---|
스칼라 강의 (43) - 고급 타입관련 주제들 (0) | 2017.03.26 |
스칼라 강좌 (41) Try 예외처리 (0) | 2017.02.27 |
스칼라 강좌 (40) 동시성을 위한 Promise 와 Await (0) | 2017.02.21 |
스칼라 강좌 (39) 동시성을 위한 Observable (0) | 2017.02.21 |