2014-06-22 2 views
0

제네릭 기반 테스트와 함께 사용하기 위해 제네릭 빌더 암시 적 typeclass를 만드는 것이 연습 중입니다. 아래 예제는 필수 로직을 포착합니다.유형 다형 적 암시 적 클래스 컴파일 오류

/Users/pkinsky/genBuilder.scala:19: error: value self is not a member of Main.$anon.Foo.GenBuilder[T] 
      _items = _items + that.self 

이 컴파일러 오류가 나에게 혼동 다음 컴파일 오류

object Foo { 
    trait FooLike[A] { 
     def foo(a: A): String 
    } 

    object FooLike { 
     implicit object FooLikeInt extends FooLike[Int] { 
      override def foo(a: Int): String = a.toString 
     } 
    } 

    implicit class GenBuilder[T](self: T)(implicit f: FooLike[T]){ 

     private var _items = Set(self) 

     def |?|(that: GenBuilder[T]): GenBuilder[T] = { 
      _items = _items + that.self 
      this 
     } 

     def items: Set[String] = _items.toSet.map((a: T) => f.foo(a)) 
    } 

} 

object Test { 
    import Foo._ 
    import Foo.FooLike._ 
    def test = { 
     val res = 11 |?| 12 |?| 13 |?| 14 
     println(res.items) 
    } 
} 


Test.test 

결과 (대신 형 FooLike의 구성원을 결합, GenBuilder는 scalacheck의 세대 형질의 구성원을 결합하는 데 사용됩니다) 어떻게 자신이 GenBuilder [T]의 멤버가 될 수 없습니까?

(참고 : 그 스칼라의 타입 시스템 부두에 영향이있는 경우 나, '스칼라 $ 파일 이름'을 사용하여 스크립트로 이것을 실행하는거야) 어떻게 든, 아래의 코드가 작동

+1

'val self : T'를 생성자 매개 변수에 넣으면 어떨까요? – ggovan

+0

오 세상에, 나는 바보 야. case 클래스 만 val이없는 ​​생성자 매개 변수를 자동으로 노출합니다. 이것은 깊은 타입 시스템 부두가 아니며, 이것은 분명히 나를 때리는 것입니다. 크레딧을 원할 경우이 댓글을 답으로 추가하십시오. :) – pkinsky

답변

1

의 경우 일부 깊은 형 시스템 부두 아니라 생성자의 매개 변수가 스칼라에서 사용되는 다른 방법이 아니다.

오히려 constructor에/개인에 바로 사용 가능한보다는 GenBuilder의 필드 self를 만들 것입니다

implicit class GenBuilder[T](val self: T)(implicit f: FooLike[T]){ 

합니다 ( 자기 주)에 클래스 헤더를 변경.

사례 클래스는 모든 매개 변수를 사용하여 자동으로이를 수행합니다.

0

. that.selfthat.getSelf으로 바꾸는 것은 def getSelf: T = self으로 바꾸고 컴파일하고 작동하게하여 예상대로 Set(11, 12, 13, 14)을 인쇄합니다. 출시 예정 : 다음 질문, 내가 왜 묻는가? 왜이게 효과가 있니?

object Foo { 
    trait FooLike[A] { 
     def foo(a: A): String 
    } 

    object FooLike { 
     implicit object FooLikeInt extends FooLike[Int] { 
      override def foo(a: Int): String = a.toString 
     } 
    } 

    implicit class GenBuilder[T](self: T)(implicit f: FooLike[T]){ 

     private var _items = Set(self) 
     def getSelf: T = self 

     def |?|(that: GenBuilder[T]): GenBuilder[T] = { 
      that.getSelf 
      _items = _items + that.getSelf 
      this 
     } 

     def items: Set[String] = _items.toSet.map((a: T) => f.foo(a)) 
    } 

} 

object Test { 
    import Foo._ 
    import Foo.FooLike._ 
    def test = { 
     val res = 11 |?| 12 |?| 13 |?| 14 
     println(res.items) 
    } 
} 


Test.test