พิจารณาตัวอย่าง Kotlin น้อยที่สุดต่อไปนี้:
fun <U> someWrapper(supplier: () -> U): () -> (U) {
return { supplier() }
}
fun foo(taskExecutor: TaskExecutor): Int {
val future = CompletableFuture.supplyAsync(someWrapper {
42
}, taskExecutor::execute)
return future.join()
}
@Test
public void shouldFoo() {
assertThat(foo(), is(42));
}
ฉันมีกฎความครอบคลุมสาขาใน Jacoco ซึ่งไม่สามารถใช้รหัสด้านบนได้กล่าวว่า 1 ใน 2 สาขาไม่ครอบคลุมในสายของการsomeWrapper
โทร น่าเสียดายที่มันไม่มีตัวเลือกให้ฉันยกเว้นชั้นเรียนทั้งหมดที่someWrapper
ถูกเรียก
ดูโค้ด Java ที่แยกส่วนแล้ว:
public final int foo(TaskExecutor taskExecutor) {
Object var10000 = WrappersKt.someWrapper((Function0)null.INSTANCE);
if (var10000 != null) {
Object var2 = var10000;
var10000 = new Foo$sam$java_util_function_Supplier$0((Function0)var2);
}
Supplier var3 = (Supplier)var10000;
Function1 var4 = (Function1)(new Function1(this.taskExecutor) {
// $FF: synthetic method
// $FF: bridge method
public Object invoke(Object var1) {
this.invoke((Runnable)var1);
return Unit.INSTANCE;
}
public final void invoke(Runnable p1) {
((TaskExecutor)this.receiver).execute(p1);
}
public final KDeclarationContainer getOwner() {
return Reflection.getOrCreateKotlinClass(TaskExecutor.class);
}
public final String getName() {
return "execute";
}
public final String getSignature() {
return "execute(Ljava/lang/Runnable;)V";
}
});
CompletableFuture future = CompletableFuture.supplyAsync(var3, (Executor)(new Foo$sam$java_util_concurrent_Executor$0(var4)));
var10000 = future.join();
Intrinsics.checkExpressionValueIsNotNull(var10000, "future.join()");
return ((Number)var10000).intValue();
}
ฉันคิดว่าปัญหาคือif (var10000 != null)
สาขาซึ่ง IDE ทำเครื่องหมายว่าไม่จำเป็น (จริงเสมอ)
เป็นไปได้ไหมที่จะปรับรหัสเพื่อให้ครอบคลุมทุกสาขาเช่น โดยทำให้แน่ใจว่าคอมไพเลอร์ไม่ได้สร้างการตรวจสอบโมฆะพิเศษนั้น? ฉันสามารถเปลี่ยนรหัสของทั้งสองfoo(..)
และsomeWrapper(..)
ตราบใดที่ฉันสามารถจัดหาแลมบ์ดาที่ตกแต่งได้
ฉันใช้ Kotlin 1.3.50 และ Jacoco 0.8.4
แก้ไข
วิธีแก้ไขปัญหาหนึ่งที่ชัดเจนคือการแยกsupplyAsync(someWrapper { ... })
ไปยังคลาส utils และยกเว้นคลาสนั้นเท่านั้นเช่น:
fun <U> supplyAsync(supplier: () -> U, executor: TaskExecutor): CompletableFuture<U> {
return CompletableFuture.supplyAsync(someWrapper { supplier() }, executor::execute)
}
นี่จะดีพอสำหรับฉัน แต่ฉันก็ยังสงสัยว่าทำไม Kotlin จึงถูกเพิ่มสาขาที่ไม่จำเป็นต้องสาขา
Type inference failed
เมื่อพยายามทำให้โค้ดตัวอย่างของคุณรวบรวม คงจะดีมากถ้าคุณสามารถให้โค้ดตัวอย่างที่ใช้งานได้! ตัวอย่างเช่นtaskExecutor
และcontroller
ไม่เป็นที่รู้จัก