2024 02 29
2024-02-29¶
Slick의 filter에서 Some/None을 사용하지 못하는 현상¶
- 문제
- 테이블 칼럼에 다음과 같은 값이 있었음
def displayStartAt = column[Option[LocalDateTime]]("display_start_at")
- 이 상황에서 테이블에 filter를 걸었는데
Bulletin.filter(_.displayStartAt === Option(LocalDateTime.now()))는 OKBulletin.filter(_.displayStartAt === Some(LocalDateTime.now()))는 NOBulletin.filter(_.displayStartAt === None)도 No
- 테이블 칼럼에 다음과 같은 값이 있었음
- 이유
Option과Some/None은 스칼라에서 다르게 동작-
OptionOption(LocalDateTime.now)는Option.apply를 통해Some혹은None을 반환
- 이는
Option이 자체적으로 null-check를 해주고 있다는 것Some
- 반면,
Some(LocalDateTime.now)는 직빵으로Some()으로 감싸는데, 이는 null-check 할 여지를 주지 않음
- 이때
LocalDateTime.now가 null이라면, 직빵으로 NPE가 터짐None
None도 마찬가지
- Slick에서는...
- Slick에서는 DB 칼럼과 None을 직빵으로 비교하는 것에 대해 제재를 하고 있음 (NPE 터질 수 있으니)
- 그래서 Option의
isEmpty사용하도록 권장 .filter(_.displayStartAt.isEmpty)
Scala에서 Option/Some/None의 확실한 관계¶
참고: https://medium.com/@sukumaar/scala-option-some-none-b9f735acfb82 참고: https://hamait.tistory.com/649
- Option은 컨테이너처럼 동작하여,
- 참조가 empty(메모리 어딘가를 참조중이면) => Some
- 아니라면 => None
- 그러다 보니 case-match와 호환성이 좋네 (컨테이너니까)
- Option
- 값이 있거나/없거나 한 상태를 나타냄
- 값이 담겨져 있다면 => Some[T]
- 값이 없으면 => None
- Option은 Try,Future와 함께 대표적인 모나딕 컬렉션
- 두 가지 생각하자
- Null을 안전하게 다루자!
- 연속체인에서 안정적으로 사용하자!
- 값이 있거나/없거나 한 상태를 나타냄
- Option 활용처
- Map
Scala Monadic Collection¶
Iterable연산과 비슷한 변형 연산을 지원하지만, 하나 이상의 요소를 포함할 수 없는 컬렉션- Option
- 안전한 null 처리
Some/None타입으로 값의 존재 구분isDefined,isEmpty사용해 값 유무 판단 가능- 일반적인 컬렉션에서도 요소 추출시
Option반환을 통한 안정성 확보할 수 있음 .get()은 비권장. 딴거 쓰자.getOrElse().fold(): None일 경우 해당값 리턴, Some일 경우 고차함수 실행
- Try
- 기존 자바 try/catch를 스칼라의 Try로 바꿔보자!
- 스칼라에서도 try/catch 블록을 지원하고, catch 블록에서 발생한 에러를 매칭하는 case 문 포함할 수 있다
- 하지만
util.Try만 사용함으로써 안전/표현력/모나딕 접근법이 가능하다
- 하지만
- Try를 세련되게 다뤄보자
-
Future
- 백그라운드 작업을 개시하는 컬렉션
- 기본적으로 스칼라 코드는 JVM의 메인 쓰레드에서 동작하나,
Future의 사용은 별도 쓰레드에서 백그라운드 작업이 가능케 한다- 다만 백그라운드로 돌리기 위해서는 실행하기 위한
Context를 지정해야 함
- 다만 백그라운드로 돌리기 위해서는 실행하기 위한
- 기본 사용법
- 명시적으로
context지정
- 묵시적으로
context지정