일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 블록체인
- 안드로이드 웹뷰
- 파이썬 데이터분석
- Adapter 패턴
- Play2
- Akka
- 하이브리드앱
- akka 강좌
- Hyperledger fabric gossip protocol
- 플레이프레임워크
- Golang
- 파이썬
- play2 강좌
- hyperledger fabric
- 하이퍼레저 패브릭
- 스칼라 동시성
- 파이썬 동시성
- 스위프트
- play 강좌
- 스칼라
- 파이썬 머신러닝
- 그라파나
- Play2 로 웹 개발
- Actor
- 이더리움
- CORDA
- 주키퍼
- 엔터프라이즈 블록체인
- 스칼라 강좌
- 파이썬 강좌
- Today
- Total
HAMA 블로그
스칼라 강좌 (21) - Option 과 Either 본문
Option
값이 있거나 또는 없거나 한 상태를 나타낼 수 있는 타입이다.
값이 담겨져 있는 Option 의 하위 타입은 Some[T] 이며, 값이 없으면 None 이다.
Option 은 Try, Future 등과 함께 대표적인 모나딕컬렉션 이다. "컬렉션" 이다.
보통 Option 을 떠올리면 2가지를 생각해야한다.
1. null 을 안전하게 대체하기 위해 만들어진 것.
-> 사용자에게 주의를 다시 한번 당부하는 것으로, null 예외가 발생할 확률을 없앤다.
2. 연속체인에서 안정적으로 사용하기 위한 것
-> 연속으로 계산되는 상황에서 안정적으로 실행된다. 즉 중간에 문제가 생기는것을 방어한다. 주의 할 것은 방어가 되는 함수는 따로 있다는 것이며 아래 표에서 자세히 설명된다.
Option 이 사용되는 경우
val numbers = Map("one" -> 1, "two" -> 2)
val h2 : Option[Int] = numbers.get("two")
이 경우 h1 에는 값이 담겨져 있는 Option 을 받을 것이다. 즉 Some 타입을 받을 것이고
val numbers = Map("one" -> 1, "two" -> 2)
val h3 : Option[Int] = numbers.get("three")
이 경우 h3 에 해당 되는 값이 없기 때문에 Option 은 None 이 될 것이다.
Option 에서 값 가져오기 (get 과 isDefined 사용하기)
val h3 : Option[Int] = numbers.get("three")
이 경우 h3 이 Some 인지 None 인지 어떻게 알까? 확인하고 사용해야지 않을가?
그때 isDefined 메소드를 사용한다. (반대 개념의 isEmpty 도 있다.)
if (h3.isDefined)
println (h3.get)
요렇게 확인해서 값을 사용 할 수 있다. Option 타입에서 실제 값을 가져오는 함수는 get 이다.
getOrElse 로 사용하기
def testOption(o : Option[Int]) = {
println(o.getOrElse("nothing"))
}
getOrElse 를 사용하여 값이 있으면 그 값을 사용하고 , 없으면 인자로 넘긴 "nothing" 을 사용하게 한다.
패턴 매칭으로 로 사용하기
def testOption(o : Option[Int]) = {
val result = o match {
case Some(n) => n
case None => "nothing" }
}
match 를 사용하여 값이 있으면 즉 Some(n) 으로 매칭되면 값 사용 , 없으면 "nothing" 을 사용하게 한다.
Option 타입의 파라미터 사용
def testOption(o : Option[Int]) = {
...
}
testOption(Some(10))
옵션타입을 인자로 받는 함수에 값을 넘길때는 값을 직접 넘길 수 없다. Some 타입으로 만들어서 넘긴다.
Option 타입을 map 으로 연결 해보자.
case class Employee(name: String, department: String)
def lookupByName(name: String) : Option[Employee] = ...
val joeDepartment: Option[String] = lookupByName("joe").map(_.department)
이렇게 map 으로 연결 할 수 있다. 즉 map 은 Option 타입을 스스로 변경하여 적용한다.
근데 여기서 None 이 맵으로 들어 가면 어떻게 될까? 그냥 나머지 계산이 취소되어서 아무것도 안한다.
Option 은 스칼라에서의 가장 기본적인 모나드라고 한다.
추가적으로 Try, Future 등도 대표 모나딕컬렉션이다.
안전한 Option 추출 정리
fold |
nextOption.fold(-1)(x=>x) |
Some(이 경우 내장값)인 경우 주어진 함수로부터 추출한 값을,None인 경우 시작값을 반환함,foldLeft,foldRight,reduceXXX 메소드로도 Option 을 그 내장된 값 아니면 계산된 값으로 축소할 수 있음 |
getOrElse |
nextOption getOrElse 5 또는 |
Some의 값을 반환하거나 아니면 이름 매개변수의 결과를 반환함 |
orElse |
nextOption orElse nextOption |
실제로 값을 추출하지는 않지만,None인 경우 값을 채우려함. Option이 비어 있지 않으면 이 Option을 반환하고, 그렇지 않은 경우 주어진 이름 매개변수로부터 Option 을 반환함 |
match 표현식 |
nextOption match { case Some(x) =>x; |
값이 있는 경우 매치 표현식을 사용하여 그 값을 처리함, Some(x) 표현식은 그 데이터를 추출하여 매치 표현식의 결과값으로 사용되거나 또 다른 변환에 재사용할 수 있는 지정된 값'x' 에 넣음 |
* 러닝스칼라 (제이슨스와츠,제이펍 발생) 에서 발췌
Either
둘 중 하나의 값을 가질 수 있는 타입이다.
Either 에 값 담기
def eitherTest(num: Option[Int]): Either[String, Int] = num match {
case Some(n) => Right(n)
case None => Left("Error! Number is missing!")
}
eitherTest(Some(7))
eitherTest 메소드를 살펴보자.
인자로 제대로 된 값이 들어오면 Right 즉 Either 의 오른쪽에 담고
인자에 제대로 된 값이 안 들어오면 Left 즉 Either 의 왼쪽에 값을 담는다.
Either 값 사용하기
val res = eitherTest(Some(7))
if( res.isRight ) println("Number is %s".format(res.right.get))
else if( res.isLeft) println("Error message => %s".format(res.left.get))
eitherTest 메소드를 호출해서 받는 값 res 는 Either[String, Int] 타입인데 어느쪽에 제대로 된 값이 들어 있는 지 확인하기 위해서 res.isRight / res.isLeft 를 사용했다.
패턴 매칭으로 사용하기
val result = eitherExample(Some(7)) match {
case Right(num) => num
case Left(err) => err
}
다음 처럼 패턴 매칭을 사용 할 수 도 있다.
레퍼런스:
러닝 스칼라
프로그래밍 인 스칼라
'Scala' 카테고리의 다른 글
스칼라 강좌 (23) - Null 과 친구들 (None, Nil, Unit) (0) | 2016.09.30 |
---|---|
스칼라 강좌 (22) - apply 정리 (0) | 2016.09.30 |
스칼라 강좌 (20) - 고차함수들 (zip,map,flatmap등) (0) | 2016.08.14 |
스칼라 강좌 (19) - implicit (0) | 2016.08.13 |
스칼라 강좌 (18) -trait (1) | 2016.08.06 |