在查看有关functional error handling的箭头文档时,列出的避免抛出异常的原因之一是性能成本(参考The hidden performance costs of instantiating Throwables)
因此,建议将错误/故障建模为Effect
。
当构建Effect
来中断计算时,应该使用shift()
方法(在幕后,它也是用于通过bind()
方法“展开”效果的方法)。
看一下shift()
方法实现,似乎它的魔力已经完成了...抛出异常,这意味着不仅在我们想要发出错误信号时创建异常,而且还“解开”任何丢失的Option
、Either
的Left
示例以及库公开的所有其他效果类型。
我不明白的是,是否做了一些优化来避免“示例化Throwables的隐藏性能成本”的问题,或者最终它们不是一个真实的的问题?
1条答案
按热度按时间0lvr5msh1#
我不明白的是,是否做了一些优化来避免“示例化Throwables的隐藏性能成本”的问题,或者最终它们不是一个真实的的问题?
这是在JVM上使用类型化错误的 * 最大原因 * 的说法可能是言过其实了,使用类型化错误有更好的理由。异常不是类型化的,所以编译器不会跟踪它们。如果你关心类型安全或纯度,这是我们想要避免的。这将在文档或2.x.x中得到更好的反映。
在热循环中,避免性能损失可能是一个好处,但在一般应用程序编程中,它可能被忽略。
然而,为了回答你关于Kotlin和Arrow如何处理这一问题:
在Kotlin中,协程的取消是通过
CancellationException
来实现的,所以在Kotlin语言中需要使用这个机制来正确工作。你可以在Arrow 2.x.xRaise
design document中找到更多的细节。它可以消除异常的性能损失。这也是Arrow正在做的事情。(除了单个版本中的一个小的回归,这个问题在下一个版本中得到了修复)。
在官方的KotlinX协程中也可以找到这样的一个例子,它对
JobCancellationException
的禁用堆栈跟踪应用了相同的技术。