我定义了如下函数:
inline fun <T> T.tryTo(block: T.() -> Unit): T? {
try {
block()
} catch (ex: IllegalArgumentException) {
return this
}
return null
}
字符串
其目的是在对象上构建尝试操作链,例如:
val input: String = getInput();
input.tryTo /* treat as a file name and open the file */ {
Desktop.getDesktop().open(File(this))
}?.tryTo /* treat as a number */ {
try {
doSomethingWithTheNumber(parseInt(this))
} catch (ex: NumberFormatException) {
throw IllegalArgumentException()
}
}?.tryTo {
println("All options tried, none worked out. Don't know how to treat this input.")
}
型
到目前为止一切正常。
但是,正如您在中间的 tryTo-block(“treat as a number”)中所看到的,将“expected”异常作为IllegalArgumentException重新抛出以保持模式工作是不方便的。最好是这样写:
val input: String = getInput();
input.tryTo<IllegalArgumentException> /* treat as a file name and open the file */ {
Desktop.getDesktop().open(File(this))
}?.tryTo<NumberFormatException> /* treat as a number */ {
doSomethingWithTheNumber(parseInt(this))
}?.tryTo<Exception> {
println("All options tried, none worked out. Don't know how to treat this input.")
}
型
因此,我将函数 tryTo 重写为:
inline fun <T, X: Exception> T.tryTo(block: T.() -> Unit): T? {
try {
block()
} catch (ex: X) {
return this
}
return null
}
型
不幸的是,后者无法编译:“类型参数禁止用于catch参数”。
如何规避此限制?
附录:
现在我得到了它:
inline fun <T, reified X: Exception> T.tryTo(block: T.() -> Unit): T? {
try {
block()
} catch (ex: Exception) {
return if (ex is X) this else throw ex
}
return null
}
型
但我仍然不满意,因为它要求我显式地指定两个类型(“类型推断失败...”/“需要2个类型参数...”):
input.tryTo<String, IllegalArgumentException> /* treat as a file in the stapel-directory */ {
...
}
型
尽管第一类型参数显然是可从接收器对象推断的。
3条答案
按热度按时间xoefb8l81#
我认为这是可能的,如果你只是使类型参数具体化,但显然不是。我确实找到了这个检查的源代码,很明显,它对catch子句中的任何类型的参数都是错误的,无论它是否被具体化。
添加这些检查的提交消息引用了this issue-显然,带有类型参数的catch子句捕获了所有抛出的
Exception
示例,如果异常不是指定的类型,则会崩溃并返回ClassCastException
。对于你的情况,一个可能的解决方法来自this answer,用于类似的Java问题-如果泛型类型被具体化,你可以检查抛出的异常是否是该特定类型,我相信这使这个函数成为你所寻找的:
字符串
虽然调用位置变得非常丑陋,因为如果函数调用有两个类型参数,你不能只指定它的第二个类型参数:
型
一个稍微好一点的替代方案,更接近原始的Java答案:
型
传入
KClass
示例如下:型
gxwragnw2#
您可以简单地删除receiver参数
对于
else
语义,最好使用?:
,然后使用?.
字符串
nhaq1z213#
字符串