어떻게 자바 호출자의 '무효'반환 형식으로 코 틀린 람다를 선언?

Chriss :

나는 완전히 공개 API를 포함하여 코 틀린로 작성된 라이브러리를 가지고있다. 이제 라이브러리의 사용자가 자바를 사용, 여기에 문제는 반환 형식과 코 틀린 람다가 있다는 것입니다 Unit반환 형식으로 컴파일되지 않습니다 void. 효과는 자바 측이 반환 항상 가지고 있다는 것입니다 Unit.INSTANCEeffectivly있는 방법에 대해 void. 이것은 어떻게 든 피할 수 있습니까?

예:

코 틀린 람다

interface Foo{
  fun bar(x:(String)->Unit)
}

자바 호출

public void call(){
   foo.bar(this::processString)
}

//the return type should rather be void instead of Unit
public Unit processString(String s){  
    return Unit.INSTANCE 
    // ^^ implementations should not be forced to return anything 
 }

그것은 컴파일러가 생성되도록 다르게 코 틀린 람다를 선언하는 것이 가능 void반환 유형을?

또한 참조 자바 호출자의 '무효'반환 형식과 코 틀린 함수를 선언하는 방법?

롤랜드 :

나는이에 진짜 대답이 없어,하지만 난 공유, 내가 액세스와 같은 코 틀린 자바의 코드 (또는 무엇을 내 마음에왔다)에 필요한 이러한 상황에서 무슨 짓을했는지.

기본적으로 그것은 당신이 정말로 향상 단지 필요한 것을 얻을 / 터치합니다 어느 쪽 달려있다.

자바 등가물을 지원하기 위해 코 틀린 코드를 향상 :

interface Foo {
  fun bar(x : (String) -> Unit)

  /* the following is only here for Java */
  @JvmDefault // this requires that you add -Xjvm-default=enable to your compiler flags!
  fun bar(x:Consumer<String>) = bar(x::accept)
}

이것은 몇 가지 단점을 가지고 다음 Consumer-method가 아니라 코 틀린에서 볼 수 있으며, 따라서 또한 호출 거기에서이다. 도없이 그냥 더 부풀어 얻을 때문에 전체 코 틀린-인터페이스를 인터페이스의 모든 기능을 복제하고 필요가 있다고 말할 수 있습니다. 그러나 : 그것은 양쪽에서 당신이 기대하는 방식으로 작동합니다. 자바는 호출 Consumer코 틀린이 호출 -variant을 (String) -> Unit-variant ... 희망 ;-) 사실 그냥 통화를 시연를 :

// from Java:
..bar(s -> { System.out.println(s); })
// however, method references might not work that easily or not without a workaround...
..bar((Consumer<String>) System.out::println); // not nice... @JvmName("kotlinsBar") to the rescue? well... that will just get more and more ugly ;-)

// from Kotlin:
..bar(Consumer(::println)) // or: ..bar(Consumer { println(it) })
..bar(::println)           // or: ..bar { println(it) } // whatever you prefer...

말했다 갖는 또 다른 변형은 다음과 같이 실제로 도움이 자바에서 코 틀린 기능을 쉽게 호출 도우미 방법, 예를 들어 뭔가를 추가하는 것입니다 :

fun <T> `$`(consumer: Consumer<T>): (T) -> Unit = consumer::accept

아마 코 틀린에서 호출되지 않습니다 어떤합니다 ($와 결합 된 역 따옴표를 쓰기로 이미 성가신 충분하다) 또는 당신이 당신의 코 틀린 코드를 부풀게하고 싶지 않다면 단지 그러나 그것은 그 슬림을 보이지 않는 자바, 그러한 방법을 추가 :

static <T> Function1<T, Unit> $(Consumer<T> consumer) {
    return t -> {
        consumer.accept(t);
        return Unit.INSTANCE;
    };
}

이러한 메서드 호출은 모두 같은 모양 :

..bar($(s -> /* do something with s */)) // where bar(x : (String) -> Unit)

일을 위해 난 그냥 돌아 해결하는 데 필요한 Unit.INSTANCE이나 null,하지만 난 더 방법이 있다면 아마 두 번째 (선택했을 호출하는 $(...)) 방법을. 최선의 경우 난 단지 (생성? ;-)) 동등 제공해야 한 번 공급 반면 여러 프로젝트에서 사용할 default아마도 방법으로 더 많은 작업이 필요합니다 단지 Java 용 인터페이스의 변형을, 심지어 어떤 사람들을 혼동 할 수있다 ...

마지막으로 : 아니 ... 난 당신이 같은 것을 가질 수있는 옵션을 몰라 void의 아웃 - 기능 인터페이스 (/ 소비자) Unit코 틀린의 -returning 기능 인터페이스를.

추천

출처http://43.154.161.224:23101/article/api/json?id=137865&siteId=1