def forceR[B](that: IO[B]): IO[B] =
// cast is needed here to trick the compiler into avoiding the IO[Any]
asInstanceOf[IO[Unit]].handleError(_ => ()).productR(that)
asInstanceOf[IO[Unit]]
把自己变成一个IO[Unit]
handleError
具有类型 def handleError[B >: A](f: Throwable => B): IO[B]
通常统计返回的类型绑定 IO[B]
应该是 IO[Unit]
那为什么调用站点上的这个
forceR
定义有真正的IO[B]
类型如IO[Int]
?
你的问题有点令人困惑。
那为什么调用站点上的这个
定义有真正的forceR
类型如IO[B]
?IO[Int]
因为
forceR
的返回类型指定为IO[B]
。所以它在调用站点不能是任何其他东西(如果代码编译)。
我猜你误解了评论
// cast is needed here to trick the compiler into avoiding the IO[Any]
这不是为了避免返回类型
IO[Any]
。由于IO[B]
,返回类型无论如何都是productR
,@GaëlJ是正确的
sealed abstract class IO[+A] ... {
...
def productR[B](that: IO[B]): IO[B] =
flatMap(_ => that)
So this is not intended to make
this.handleError(_ => ()).productR(that)
not IO[Any]
, this seems to be intended to make this.handleError(_ => ())
not IO[Any]
.
如果
this
是 IO[A]
和 A <: AnyVal
那么 this.handleError(_ => ())
的类型是 IO[AnyVal]
。如果不是 A <: AnyVal
那么 this.handleError(_ => ())
的类型是 IO[Any]
。不知道为什么它在handleError
中很重要。 .getClass
中用到了一些反射(handleError
),缓存,堆栈跟踪。 IO[Any]
. 可能不需要错误消息
def handleError[B >: A](f: Throwable => B): IO[B] =
handleErrorWith[B](t => IO.pure(f(t)))
def handleErrorWith[B >: A](f: Throwable => IO[B]): IO[B] =
IO.HandleErrorWith(this, f, Tracing.calculateTracingEvent(f))
def calculateTracingEvent(key: Any): TracingEvent = {
if (isCachedStackTracing) {
val cls = key.getClass
get(cls)
} else if (isFullStackTracing) {
buildEvent()
} else {
null
}
}
/**
* Holds platform-specific flags that control tracing behavior.
*
* <p>The Scala compiler inserts a volatile bitmap access for module field accesses. Because the
* `tracingMode` flag is read in various IO constructors, we are opting to define it in a Java
* source file to avoid the volatile access.
*
* <p>INTERNAL API with no source or binary compatibility guarantees.
*/
public final class TracingConstants {...}
否则,也许铸造只是一种预防措施,实际上并不是必需的:)
Daniel Spiewak @djspiewak 添加演员表的具体提交在这里