Scala 尝试和奇怪的行为
Scala Try and Either Weird Behavior
所以我在 Scala 中使用 M
类型,并提出了以下关于 Try
和 Either
的内容:
def brokers(throw1: () => List[Int], throw2: List[Int] => List[String]) = {
println("brokers ===> " +
(Try(throw1())
.toEither
.filterOrElse(!_.isEmpty, Nil)
.flatMap(xs => Try(throw2(xs)).toEither) match {
case Right(s) => s
case Left(f) => throw f.asInstanceOf[Throwable]
})
)
}
还有一些测试 运行s:
brokers(() => List(1, 2, 3), (xs: List[Int]) => xs.map(_.toString))
brokers(() => Nil, (xs: List[Int]) => throw new RuntimeException("throw2"))
brokers(() => Nil, (xs: List[Int]) => xs.map(_.toString))
brokers(() => throw new RuntimeException("throw1"), (xs: List[Int]) => xs.map(_.toString))
brokers(() => List(1, 2, 3), (xs: List[Int]) => throw new RuntimeException("throw2"))
但是:
throw f
无法编译:"Expression of type Serializable doesn't conform to expected type Throwable"。因此演员表。
- 样本异常 运行 2:
Exception in thread "main"
java.lang.ClassCastException: scala.collection.immutable.Nil$ cannot
be cast to java.lang.Throwable at
Practice$.brokers(Practice.scala:57) at
Practice$.delayedEndpoint$Practice(Practice.scala:63)
为什么,Scala,为什么?
回答我自己的问题,结果 Either.filterOrElse
并不是我想的那样。如果谓词不匹配,filterOrElse
实际上会将 Either[A, B]
转换为 Either[AA, B]
,其中 AA
是提供给 filterOrElse
的 "zero" 元素。在我的例子中,它将 Either[Throwable,List[Int]] = Right(List())
转换为 Either[java.io.Serializable,List[Int]] = Left(List())
。因此编译错误,与 case Left
的匹配和最终的异常。 Serializable
一定来自逆变类型参数 AA >: A
,因为猜猜看,Throwable
和 List
的第一个公共超类型是 Serializable
.
我已为此提交 SI-10044;看看他们怎么说。
所以我在 Scala 中使用 M
类型,并提出了以下关于 Try
和 Either
的内容:
def brokers(throw1: () => List[Int], throw2: List[Int] => List[String]) = {
println("brokers ===> " +
(Try(throw1())
.toEither
.filterOrElse(!_.isEmpty, Nil)
.flatMap(xs => Try(throw2(xs)).toEither) match {
case Right(s) => s
case Left(f) => throw f.asInstanceOf[Throwable]
})
)
}
还有一些测试 运行s:
brokers(() => List(1, 2, 3), (xs: List[Int]) => xs.map(_.toString))
brokers(() => Nil, (xs: List[Int]) => throw new RuntimeException("throw2"))
brokers(() => Nil, (xs: List[Int]) => xs.map(_.toString))
brokers(() => throw new RuntimeException("throw1"), (xs: List[Int]) => xs.map(_.toString))
brokers(() => List(1, 2, 3), (xs: List[Int]) => throw new RuntimeException("throw2"))
但是:
throw f
无法编译:"Expression of type Serializable doesn't conform to expected type Throwable"。因此演员表。- 样本异常 运行 2:
Exception in thread "main" java.lang.ClassCastException: scala.collection.immutable.Nil$ cannot be cast to java.lang.Throwable at Practice$.brokers(Practice.scala:57) at Practice$.delayedEndpoint$Practice(Practice.scala:63)
为什么,Scala,为什么?
回答我自己的问题,结果 Either.filterOrElse
并不是我想的那样。如果谓词不匹配,filterOrElse
实际上会将 Either[A, B]
转换为 Either[AA, B]
,其中 AA
是提供给 filterOrElse
的 "zero" 元素。在我的例子中,它将 Either[Throwable,List[Int]] = Right(List())
转换为 Either[java.io.Serializable,List[Int]] = Left(List())
。因此编译错误,与 case Left
的匹配和最终的异常。 Serializable
一定来自逆变类型参数 AA >: A
,因为猜猜看,Throwable
和 List
的第一个公共超类型是 Serializable
.
我已为此提交 SI-10044;看看他们怎么说。