[SCALA] 하나를 사용하여 스칼라 코드에서 오류를 처리하는
SCALA하나를 사용하여 스칼라 코드에서 오류를 처리하는
옵션 모나드는 스칼라에서 뭔가 아니면도 일을 처리 할 수있는 좋은 표현 방법입니다. 그러나 하나는 "아무것도"발생시 메시지를 기록 무엇을해야하는지? 스칼라 API 문서에 따르면,
그러나, 나는 중 하나 또는 어느 처리 실패에 대한 관련된 좋은 실제 사례를 사용하여 모범 사례를 찾을 수 운이 없었다. 마지막으로 나는 내 자신의 프로젝트에 대한 다음 코드로 왔어요 :
def logs: Array[String] = {
def props: Option[Map[String, Any]] = configAdmin.map{ ca =>
val config = ca.getConfiguration(PID, null)
config.properties getOrElse immutable.Map.empty
}
def checkType(any: Any): Option[Array[String]] = any match {
case a: Array[String] => Some(a)
case _ => None
}
def lookup: Either[(Symbol, String), Array[String]] =
for {val properties <- props.toRight('warning -> "ConfigurationAdmin service not bound").right
val logsParam <- properties.get("logs").toRight('debug -> "'logs' not defined in the configuration").right
val array <- checkType(logsParam).toRight('warning -> "unknown type of 'logs' confguration parameter").right}
yield array
lookup.fold(failure => { failure match {
case ('warning, msg) => log(LogService.WARNING, msg)
case ('debug, msg) => log(LogService.DEBUG, msg)
case _ =>
}; new Array[String](0) }, success => success)
}
(이 실제 프로젝트에서 코드 조각입니다주의, 그래서 그 자체로 컴파일되지 않습니다하시기 바랍니다)
난 당신이 사용하는 어느 코드 및 / 또는 위의 코드를 리팩토링에 대한 더 나은 아이디어를하는 방법을 알고 감사하게 될 거라고.
해결법
-
==============================
1.하나 하나의 의미있는 결과 또는 아무것도를 반환하는 데 사용되는 옵션과는 달리, 가능한 두 개의 의미있는 결과 중 하나를 반환하는 데 사용됩니다.
하나 하나의 의미있는 결과 또는 아무것도를 반환하는 데 사용되는 옵션과는 달리, 가능한 두 개의 의미있는 결과 중 하나를 반환하는 데 사용됩니다.
예를 들어 이해하기 쉬운은 (스칼라 메일 링리스트 잠시 뒤에 순환) 아래에 주어진다 :
def throwableToLeft[T](block: => T): Either[java.lang.Throwable, T] = try { Right(block) } catch { case ex => Left(ex) }
함수 이름에서 알 수 있듯이 "블록"의 실행이 성공하면, 그것은 "오른쪽 (<결과>)"를 반환합니다. Throwable에이 발생합니다 그렇지 않으면, 그것은 "(<던질 수>) 왼쪽"을 반환합니다. 결과를 처리하는 패턴 매칭을 사용하여
var s = "hello" throwableToLeft { s.toUpperCase } match { case Right(s) => println(s) case Left(e) => e.printStackTrace } // prints "HELLO" s = null throwableToLeft { s.toUpperCase } match { case Right(s) => println(s) case Left(e) => e.printStackTrace } // prints NullPointerException stack trace
희망이 도움이.
-
==============================
2.Scalaz 라이브러리는 모두 하나 검증이라는 것이있다. 그것은보다 어느 사용으로 "유효한 결과 또는 오류 중 하나를 얻을"더 관용적이다.
Scalaz 라이브러리는 모두 하나 검증이라는 것이있다. 그것은보다 어느 사용으로 "유효한 결과 또는 오류 중 하나를 얻을"더 관용적이다.
또한 유효성 검사 오류를 축적 할 수 있습니다.
편집 : 검증이 실용적 펑터이며, \ / (발음 "disjonction"또는 "하나")라는 이름의 scalaz 하나, 모나드 때문에 "모두"하나는, complettly false입니다. 유효성 검사 오류를 accumalate 수 있다는 사실 때문에 그 성격이다. 반면에, / 처음에 정지하는 "초 정지"자연이 - \ /이 발견 ( "오류"가 "왼쪽"읽거나). 완벽한 설명은 여기에 있습니다 : http://typelevel.org/blog/2014/02/21/error-handling.html
참조 : http://scalaz.googlecode.com/svn/continuous/latest/browse.sxr/scalaz/example/ExampleValidation.scala.html
(일부 라인 제거) 위의 링크의 코멘트, 복사 / 붙여 넣기의 요청에 따라 :
// Extracting success or failure values val s: Validation[String, Int] = 1.success val f: Validation[String, Int] = "error".fail // It is recommended to use fold rather than pattern matching: val result: String = s.fold(e => "got error: " + e, s => "got success: " + s.toString) s match { case Success(a) => "success" case Failure(e) => "fail" } // Validation is a Monad, and can be used in for comprehensions. val k1 = for { i <- s j <- s } yield i + j k1.toOption assert_≟ Some(2) // The first failing sub-computation fails the entire computation. val k2 = for { i <- f j <- f } yield i + j k2.fail.toOption assert_≟ Some("error") // Validation is also an Applicative Functor, if the type of the error side of the validation is a Semigroup. // A number of computations are tried. If the all success, a function can combine them into a Success. If any // of them fails, the individual errors are accumulated. // Use the NonEmptyList semigroup to accumulate errors using the Validation Applicative Functor. val k4 = (fNel <**> fNel){ _ + _ } k4.fail.toOption assert_≟ some(nel1("error", "error"))
-
==============================
3.당신이 게시 한 조각은 매우 인위적인 것 같다. 당신은 어디에 상황에서 하나를 사용하십시오
당신이 게시 한 조각은 매우 인위적인 것 같다. 당신은 어디에 상황에서 하나를 사용하십시오
왼쪽 버튼으로 예외를 설정하면 일반적인 사용 사례, 참이다. 이상 시도 / 캐치, 그것은 예외가 예상 된 결과 인 경우 의미가 함께 코드를 유지하는 장점을 가지고 있습니다. 어느 처리하는 가장 일반적인 방법은 패턴 매칭입니다 :
result match { case Right(res) => ... case Left(res) => ... }
이 콜렉션에 나타날 때 어느 처리의 또 다른 흥미로운 방법입니다. 모음을 통해지도를 수행 할 때, 예외를 던지고 가능한하지 않을 수 있습니다, 당신은 "불가능"이외의 정보를 반환 할 수 있습니다. 양자 택일을 사용하면 수행 할 수 있습니다 그 알고리즘 과부하를하지 않고 :
val list = ( library \\ "books" map (book => if (book \ "author" isEmpty) Left(book) else Right((book \ "author" toList) map (_ text)) ) )
여기서 우리는 라이브러리에있는 모든 저자의 목록, 플러스 저자가없는 책의 목록을 얻을. 그래서 우리는 그것을 더 적절하게 처리 할 수 있습니다 :
val authorCount = ( (Map[String,Int]() /: (list filter (_ isRight) map (_.right.get))) ((map, author) => map + (author -> (map.getOrElse(author, 0) + 1))) toList ) val problemBooks = list flatMap (_.left.toSeq) // thanks to Azarov for this variation
따라서, 기본 중 하나를 사용 그렇게 간다. 그것은 특히 유용 클래스는 아니지만이 있다면 당신은 그것을 전에 본 것입니다. 다른 한편으로는 하나 쓸모가 아니다.
-
==============================
4.고양이는 예외 던지는 코드에서 하나를 만들 수있는 좋은 방법이 있습니다 :
고양이는 예외 던지는 코드에서 하나를 만들 수있는 좋은 방법이 있습니다 :
val either: Either[NumberFormatException, Int] = Either.catchOnly[NumberFormatException]("abc".toInt) // either: Either[NumberFormatException,Int] = Left(java.lang.NumberFormatException: For input string: "abc")
https://typelevel.org/cats/datatypes/either.html#working-with-exception-y-code에서
from https://stackoverflow.com/questions/1193333/using-either-to-process-failures-in-scala-code by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] dataframe으로 csv 파일을 읽는 동안 스키마를 제공합니다 (0) | 2019.11.05 |
---|---|
[SCALA] 때 등호 스칼라 방법 선언에 서명을 사용 하는가? (0) | 2019.11.05 |
[SCALA] 스칼라 함수를 정의하는 두 가지 방법. 차이점은 무엇입니까? (0) | 2019.11.05 |
[SCALA] 유용성 (실제 응용 프로그램에서와 같이) 무두질 v.s.의 스칼라의 부분 적용 (0) | 2019.11.05 |
[SCALA] SBT 조립 : 중복 제거 발견 오류 (0) | 2019.11.05 |