Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 捕获由给定KClass定义的异常<;例外情况>;在科特林?_Generics_Kotlin - Fatal编程技术网

Generics 捕获由给定KClass定义的异常<;例外情况>;在科特林?

Generics 捕获由给定KClass定义的异常<;例外情况>;在科特林?,generics,kotlin,Generics,Kotlin,例如,我想编写一个测试,它应该捕获异常的特定子类。 为此,我写 fun test(klazz: KClass<in Exception>) { try { ... } catch (e: Exception) { if (!kclazz.isInstance(e)) { throw e } else { ... } } } fun测试(klazz:

例如,我想编写一个测试,它应该捕获异常的特定子类。 为此,我写

fun test(klazz: KClass<in Exception>) {
    try {
        ...
    } catch (e: Exception) {
        if (!kclazz.isInstance(e)) {
            throw e
        } else {
            ...
        }
    }
}
fun测试(klazz:KClass){
试一试{
...
}捕获(e:例外){
如果(!kclazz.isInstance(e)){
掷e
}否则{
...
}
}
}
有没有更简单的方法在一行中实现这一点?因为我不觉得在这种情况下添加额外的类检查只是为了进一步抛出捕获的异常是一个好的解决方案。下面的代码中有类似的方法吗

fun test(klazz: KClass<in Exception>) {
    try {
        ...
    } catch (e: klazz(smth here)) {
        ...
    }
}
fun测试(klazz:KClass){
试一试{
...
}捕获(e:klazz(此处为smth)){
...
}
}

我几乎可以肯定没有,因为我尝试了许多不同的方法。但是在这种情况下,如果有人能解释为什么不可能的话,那就太酷了。

这是不可能的,因为语法

catchBlock
(used by tryExpression)
  : 'catch' '(' annotation* simpleIdentifier ':' type ')' block
  ;
,并且类型无法依赖于像
klazz
(在Kotlin中)这样的值

我试过了

inline fun <reified E : Exception> test() {
    try {
        ...
    } catch (e: E) {
        ...
    }
}

确实有效,而且可能比通过
KClass

对您来说更好因为语法

catchBlock
(used by tryExpression)
  : 'catch' '(' annotation* simpleIdentifier ':' type ')' block
  ;
,并且类型无法依赖于像
klazz
(在Kotlin中)这样的值

我试过了

inline fun <reified E : Exception> test() {
    try {
        ...
    } catch (e: E) {
        ...
    }
}

确实有效,并且可能比传递一个
KClass

对您来说更好。我使用这个高阶实用程序函数做了类似的事情:

/**
 * Asserts that the given block of code throws an exception of the specified type.
 *
 * This is much more fine-grained than `@Test(expected = ...)`, letting
 * you check that the exception was thrown by specific line(s) of code.
 *
 * @return The exception thrown.  This lets you make further tests on it
 *         (e.g. in an `also{}` block).
 * @throws AssertionError if no exception, or one of another type, was thrown.
 */
inline fun <reified T: Exception> assertThrows(exceptionClass: KClass<T> = T::class, block: () -> Unit): T {
    try {
        block()
        throw AssertionError("Should have thrown ${exceptionClass.simpleName}!")
    } catch (x: Exception) {
        if (x is T)
            return x
        throw AssertionError("Should have thrown ${exceptionClass.simpleName}, but threw $x!")
    }
}

(这不止一行,但它仍然非常简洁,读起来也很好。)

我使用这个高阶实用函数做了类似的事情:

/**
 * Asserts that the given block of code throws an exception of the specified type.
 *
 * This is much more fine-grained than `@Test(expected = ...)`, letting
 * you check that the exception was thrown by specific line(s) of code.
 *
 * @return The exception thrown.  This lets you make further tests on it
 *         (e.g. in an `also{}` block).
 * @throws AssertionError if no exception, or one of another type, was thrown.
 */
inline fun <reified T: Exception> assertThrows(exceptionClass: KClass<T> = T::class, block: () -> Unit): T {
    try {
        block()
        throw AssertionError("Should have thrown ${exceptionClass.simpleName}!")
    } catch (x: Exception) {
        if (x is T)
            return x
        throw AssertionError("Should have thrown ${exceptionClass.simpleName}, but threw $x!")
    }
}

(这不止一行,但仍然相当简洁,读起来也不错。)

谢谢!将使用最后一种方法。如果答案完全回答了您的问题,您可能希望接受答案(请参阅)。谢谢!将使用最后一种方法。如果答案完全回答了您的问题,您可能希望接受答案(请参阅)。您肯定更喜欢编写
assertThrows(){…}
?如果使用了
reified
,我不确定为什么要将
exceptionClass
作为参数传递。我认为这更符合JUnit的其他
assert…
函数。当然,其他的变体也是可能的——我并不是说这是最好的!您肯定更喜欢编写
assertThrows(){…}
?如果使用了
reified
,我不确定为什么要将
exceptionClass
作为参数传递。我认为这更符合JUnit的其他
assert…
函数。当然,其他的变体也是可能的——我并不是说这是最好的!