2017-12-02 2 views
1

내 디자인에 결함이있는 것 같습니다 (대부분은 아마도 그렇습니다). 그러나 OptionScala에 사용되고 있으며 그에 대해 너무 행복하지는 않습니다. 이제 나는이 같은 서로 호출하는 3 가지 방법이 있다고 가정 해 봅시다 : A는() I/O 작전에 의존 한, A()옵션이있는 스칼라 프로그래밍 실습

이제

def A(): reads a file and returns something 
def B(): returns something 
def C(): Side effect (writes into DB) 

C() 전화 B() 차례로 B() 호출을, 나는을 처리했다 예외 및 반환 및 Option 그렇지 않으면 컴파일하지 않습니다 (A() 아무것도 반환하지 않는 경우). B()A()에서 Option을 받고 무언가를 반환해야하므로 다른 OptionC()으로 반환해야합니다. 따라서, 내 코드에 match/case Some/case None이 넘쳐 흐르고 있다고 생각할 수 있습니다 (항상 getOrElse()을 사용할 자유는 없습니다). C()Option을 반환하는 다른 방법에 의존하는 경우 C()의 정의를 살펴볼 수 있습니다.

그래서 나는 무엇인가 놓치고 있습니까? 아니면 디자인에 결함이 있습니까? 어떻게 개선 할 수 있습니까? 당신이 Option을 버리고 당신이 None이있는 경우 Some(...) 그러나 같은 유형의 다른 값을 처리 한 후 일부 값을 생성 할 때 입력 Optionmatch/case를 사용

+2

'Option'을 사용하든 자바 방식을하든간에, 'null'또는 다른 것을 사용하여 결과가없는 경우 어떻게되는지 지정하는 코드를 작성해야합니다. 그래서 그것을 완전히 벗어날 방법이 없습니다. 참고로'match/case Some/case None'을 사용하지 않아도됩니다.'Option'도'map'과 같은 메소드를 가지므로'for'에서 사용할 수 있습니다. – Jesper

답변

0

내가 뭔가를 놓친 게 뭐죠?

Option은 하나의 디자인 결정이지만 다른 것이있을 수 있습니다. API에서 반환 한 오류를 설명 할 때 어떻게됩니까? Option은 두 가지 종류의 상태를 말할 수 있습니다. 성공적으로 값을 읽었거나 실패했습니다. 하지만 가끔 을 알고 싶다면이 실패했습니다. 파일이 없거나 예외 (예 : 파일을 읽을 수있는 권한이 없습니까?)로 인해 실패했기 때문에 더 이상 None을 반환합니다.

어느 경로를 선택 하든지 대개 하나 이상의 효과을 처리하게됩니다. Option은 부분 함수를 나타내는 이러한 효과 중 하나입니다. 즉,이 연산은 결과를 산출하지 못할 수 있습니다. 다른 말로 표현하면 Option과 패턴 매칭을 사용하는 동안이 패턴을 처리하는 한 가지 방법이 있지만 자세한 표시를 줄이는 다른 작업이 있습니다.당신이 값이 존재하는 경우에 조작을 호출하고 싶은 또 다른 경우에는 그렇지 않은 그들은 모두 같은 반환 형식이있는 경우

예를 들어, 당신이 Option.fold 사용할 수 있습니다

일반적으로
scala> val maybeValue = Some(1) 
maybeValue: Some[Int] = Some(1) 

scala> maybeValue.fold(0)(x => x + 1) 
res0: Int = 2 

, many such combinators defined on Option과 그 밖의 효과가 있습니다. 처음에는 성가신 것처럼 보일 수 있으며 나중에는 자라나고 차례로 작업을 구성 할 때 실제 힘을 보게됩니다.

3

종종 유용하다. (개인적으로, 나는 보통 이러한 상황에 대해 청소기로 fold을 찾을 수 있습니다.)

을, 다른 한편으로는, 당신이 함께 Option를 전달하는 경우 다음에 대해 가지 다른 방법이 있습니다.

def a():Option[DataType] = {/*read new data or fail*/} 

def b(): Optioon[DataType] = { 
    ... //some setup 
    a().map{ inData => 
    ... //inData is real, process it for output 
    } 
} 
def c():Unit = { 
    ... //some setup 
    b().foreach{ outData => 
    ... //outData is real, write it to DB 
    } 
} 
+0

'flatMap' 또한 마지막 시나리오 ("'C()'가'Option'을 반환하는 다른 메소드들에 의존적이라면,'C의 정의를 보는데 무서워 할 것입니다.)'_ ") – SergGr

+0

소원 나는 양쪽 대답을 받아 들일 수 있었다 :) – Mrinal

관련 문제