2012-01-31 2 views
4

(매개 변수화 된) 컬렉션을 래핑하고 클래스의 foreach 메서드를 재정의하는 스칼라에 클래스를 작성하려고합니다. foreach 메서드로 수행하는 작업은이 질문의 목적에 중요하지 않으므로 방문한대로 각 요소를 인쇄합니다. 그래서 이상적으로 우리는 래퍼를 다음과 같이 사용할 수 있습니다.매개 변수화 된 형식의 특정 작성자

scala> val a = List(1,2,3,4,5) 
scala> val b = MyWrapper(a) 
scala> b.foreach{ x => x } 
1 
2 
3 
4 
5 

핵심은 모든 반복 가능한 작업을 원한다는 것입니다. 그냥 목록이 아닙니다. 그래서 내 첫 번째 시도는이 클래스가 구체적으로, 우리는 반복자 방법 및 newBuilder 방법이 필요합니다, 그러나

class MyWrapper[A, S[A] <: Iterable[A]](val s: S[A] with IterableLike[A, S[A]]) 
     extends IterableLike[A, S[A]] { 

     override def foreach[U](f: A => U): Unit = { 
      iterator.foreach{ x => println(x); f(x) } 
     } 
} 

다음 무엇을 같은했다. 내가 newBuilder을 정의하려고하면 문제가

override def iterator = s.iterator 

: 반복자 방법은 아무 문제, 우리가 너무처럼의의 반복자를 "훔칠"수 없습니다. 나는 S [A]를 돌려 주길 빌더가 필요합니다. 그러나 S [A]는 Iterable [A]로 묶인 매개 변수화 된 모음입니다. 해당 오류 메시지가

[error] method newBuilder in trait TraversableLike of type => scala.collection.mutable.Builder[A,S[A]] is not defined 
[error] method seq in trait Parallelizable of type => scala.collection.TraversableOnce[A] is not defined 

가 어떻게 빌더를 얻을 수에 따라서 내 시도 genericBuilder를 사용하거나의 동반자 객체의 빌더 결과를 얻기의 전혀은의 Iterable [A]은은 S [A], 즉 구축보다는 제네릭 경계 형 Iterable [A]가 아닌 특정 유형, S [A]? 이것은 가능한가? 이 작업을 수행하는 관용적 인 스칼라 방법을 이해하는 데 도움이된다면 크게 도움이 될 것입니다.

+0

질문에 대한 답을 모르겠지만 반복 가능한 방식으로 방법을 포스팅 할 수 있는지 알고 싶습니다. 그렇다면 몇 줄의 코드로 'wrappedForeach'를 제공하여 원하는 것을 얻을 수 있습니다. –

+0

대신 '프록시'를 사용 해본 적이 있습니까? –

+0

안녕 다니엘. 나는 당신의 의견 앞에 프록시에 대해 몰랐다. 거기에 내가 배울 수있는 (원시 API 이외의) 리소스가 있습니까? 감사! – nomad

답변

2

IterableLike(다른 XxxLike 특성) 각 콜렉션 유형에 대해 구체적으로있는 빌더에 위임하여 반환 형식을 통해 추상입니다. 따라서 당신이 시도하는 것은 작동 할 수 없습니다.

당신은 일반적인 래퍼 MyWrapperLike을 만들 수 [A는 B] 특정 래퍼의 몇 MySeqWrapper는 [A] MyWrapperLike [A, 서열 [A] 설정 에 대한 (동일 지도를 확장 , 리스트 등), 즉 Scala 컬렉션 라이브러리의 디자인을 모방합니다.

+0

그건 재미 있어요. 따라서 S [A]에 대해 특정 (그러나 매개 변수화 된) 유형을 가지고 있다는 사실로 인해 S [A]의 특정 빌더에 어떤 방식 으로든 액세스 할 수 없습니까? S [A]에 바인딩 된 명목상의 유형이 Iterable 만 보장하기 때문입니다. 맞습니까? 특정 형식 (예 : Manifest 사용)을 어떤 방식으로 얻을 수 있습니까? – nomad