2017-11-17 9 views
0

Vavr을 사용하여 다음과 같은 Java 코드 스 니펫이 있습니다. 필자가 매개 변수를 인라인하지 않으면 유형 검사가 실패합니다.람다식이 인라 인되지 않으면 Javac이 유추 할 수 없습니다.

왜 아래 코드는 컴파일러에서 받아 들일 수 없습니까? 여기

import io.vavr.Function1; 
import io.vavr.Tuple; 
import io.vavr.Tuple2; 
import io.vavr.collection.List; 
import io.vavr.Option; 

import static io.vavr.collection.List.unfoldRight; 

class A {} 
class B {} 
class Main { 
    Function1<A, Option<Tuple2<B, A>>> f = (a) -> Option.of(Tuple.of(new B(), new A())); 
    List<B> L0 = unfoldRight(new A(), f); // * 
    List<B> L1 = unfoldRight(new A(), (a) -> Option.of(Tuple.of(new B(), new A())); 

    Option<Tuple2<B, A>> g(A a) { return Option.of(Tuple.of(new B(), new A())); } 
    List<B> L2 = unfoldRight(new A(), (a) -> g(a)); // ** 
} 


// * Compilation fails with: "Incompatible equality constraint: ? extends T and A" 

// ** Compilation fails with: "Incompatible equality constraint: ? extends A and A" 

는 Vavr 라이브러리에서 unfoldRight 방법 서명입니다 :

static <T, U> List<U> unfoldRight(T seed, Function<? super T, Option<Tuple2<? extends U, ? extends T>>> f) 

을 여기에 동일한에 대한 Github에서 문서에 대한 링크입니다 :

https://github.com/vavr-io/vavr/blob/master/vavr/src/main/java/io/vavr/collection/List.java#L644-L671

답변

1

열쇠는 점이다 Option<Tuple<A, B>>Option<Tuple<? extends A, ? extends B>>의 인스턴스가 아닙니다 (비록 Option<? extends Tuple<? extends A, ? extends B>> 임에도 불구하고).

List<Map<A, B>>List<Map<? extends A, ? extends B>> (코드와 유형 안전 측면에서 동일한 경우)을 고려하십시오. 당신이 쓸 수있는 경우 :

List<Map<A, B>> list = new ArrayList<>(); 

// Compiler error! Pretend it's OK, though. 
List<Map<? extends A, ? extends B>> list2 = list; 

Map<SubclassOfA, SubclassOfB> map = new HashMap<>(); 
list2.add(map); 

list.get(0).put(new A(), new B()); 

map 유형 A,B하지 SubclassOfA,SubclassOfB의 키/값 쌍을 포함하기 때문에, 지금 문제입니다. 따라서 map에서 물건을 가져 오려고 시도하면 ClassCastException이 표시됩니다. 따라서

Ideone demo

// ClassCastException! 
SubclassOfA soa = map.keySet().iterator().next(); 

, 그것은 컴파일러에 의해 허용되지 않는 것.

list2List<? extends Map<? extends A, ? extends B>>으로 선언 된 경우 list2.add(map)을 호출 할 수 없으므로 동일한 문제가 발생하지 않습니다. 그러므로, 그 할당은 허용 될 것이다.

Function1<A, Option<Tuple2<? extends B, ? extends A>>> f = ... 
Option<Tuple2<? extends B, ? extends A>> g(A a) { ... } 
+0

아, 맞다, 그것은'''호환되지 않는 불평등 제약의 : 와일드 카드 상한을 당신의 유형에 추가

은'''하지'''호환되지 않는 불평등 제약 (? A,를 확장) : (?는 A를 확장하고,?는 A)''를 확장합니다. 매우 감사합니다! – Zaaier