2017-02-14 12 views
0

액터의 receive 메서드와 같은 형식을 지우는 인터페이스를 통해 함수를 전달해야합니다. 그래서 지우기 형식 매개 변수를 저장하고 인수를 캐스팅하는 데 사용하고 싶습니다.유형을 지울 때 함수를 사용하는 방법은 무엇입니까?

val c0 = a0.action(source) 
val c1 = a1.action(c0) 

분명히 실패 :

class Store[R,T](val action : R => T)(implicit i : TypeTag[R], o : TypeTag[T]) { 
    val in : Type = i.tpe 
    val out : Type = o.tpe 
} 
object Store { 
    type Any = Store[_,_] 
    def apply[R,T](action : R => T)(implicit i : TypeTag[R], o : TypeTag[T]) : Store[R,T] = new Store(action) 
} 

final case class Box[T](unbox : T) 

def getType[T](x : T)(implicit t : TypeTag[T]) : Type = t.tpe 

val source = Box("test") 

val x = Store[Box[String], Box[Int]](s => Box(s.unbox.length)) 
val y = Store[Box[Int], Box[Boolean]](i => Box(i.unbox % 3 == 0)) 

val all : List[Store.Any] = List(x,y) 
val a0 = all(0) 
val a1 = all(1) 

나는 그런 체인 저장 작업을하고 싶습니다

나는 모든 종류의 런타임에 일치하는지 확인할 수 있습니다
error: type mismatch; 
found : source.type (with underlying type Box[String]) 
required: _$1 
    val c0 = a0.action(source) 
        ^
one error found 

:

assert(getType(source) <:< a0.in) 
assert(a0.out <:< a1.in) 

하지만 어떻게하면 좋을까요? 인수를 적절한 유형으로 변환 하시겠습니까? asInstanceOf에는 런타임 리플렉션이 아닌 컴파일 타임 유형이 필요합니다. 다른 트릭을 사용할 수 있습니까? 그것을 할 수

답변

1

한 가지 방법은 ClassTag[T]하고 unapply 방법을 사용하는 것입니다 : 당신이 Some[T] 값을받을 Tobject 유형이다

def castIfPossible[T](object: Any)(implicit tag: ClassTag[T]): Option[T] = 
    tag.unapply(object) 

경우, 그렇지 않으면 당신은 None를받을 수 있습니다.

코드에서 수행해야 할 것은 해당 유형이 항상 일치한다고 가정하지만 (아마도 반사는 필요 없을 것입니다) 또는 map 또는 flatMap을 함께 사용하여 값을 결합 할 수 있습니다.

개인적으로, 나는 T가 매개 변수화 된 것처럼 반성을 제거 할 수 있는지 알아보기 위해 노력할 것입니다. 그런 다음 반사가 매개 변수가 일치하는지 확인하지 않습니다. 그런 다음 문제를 처리하기 위해 형식 클래스와 같은 것을 사용할 것입니다. 그러나 나는 그것이 항상 가능하지 않을 수도 있다는 것을 이해합니다.

+0

'ClassTag [T]'는 'T'유형을 유지해야합니다. > 형식이 항상 <와 일치한다고 가정하면 문제가되지 않지만 위에 표시된 것처럼 항상 그 형식을 지정할 수 있습니다. > 클래스를 입력하십시오. 그러나 모든 유형이 손실되면 런타임에서 쓸모가 없습니다. 'Any' 타입을 받아들이는 인터페이스에 객체를 넘겨 줄 필요가 있다면 런타임 패턴 매칭 만 할 수 있습니다. – ayvango

+0

어떤 점에서'T'의 타입을 알고 있습니다 - 이것은 ClassTag를 생성 할 수있는 때입니다. 코드를 잊어 버린 부분으로 전달하십시오. 객체에 액세스하기 전에 객체를 실제로 제어 할 수없고 형식이 이미 손실 된 경우가 아니면 예외입니다. 'T'유형을 유지하는 것과 관련하여 - 반드시 그런 것은 아닙니다. 어떤 시점에서 당신은 실존 적 유형을 사용할 수 있습니다. 그러면 T는'SomeTHandler [T] (값 : T) (암시 적 태그 : ClassTag [T]) 클래스'클래스 내부에서 알 수 있지만 인터페이스 레벨 인'SomeHanlderT [_]'에서는 호언 장담 할 수 있습니다. –

+0

그리고 SomeHandlerT [_]가 타입이 이미 지워졌을 때'Option [T]'를 리턴해야한다고 어떻게 추측 할 수 있겠습니까? – ayvango