programing

암시 적 클래스는 항상 AnyVal을 확장해야합니까?

projobs 2021. 1. 16. 09:13
반응형

암시 적 클래스는 항상 AnyVal을 확장해야합니까?


확장 메서드를 작성하고 있다고 가정 해 보겠습니다.

implicit class EnhancedFoo(foo: Foo) {
  def bar() { /* ... */ }
}

항상 extends AnyVal클래스 정의에 포함해야합니까 ? 어떤 상황에서 암시 적 클래스를 값 클래스로 만들고 싶지 않습니까?


값 클래스에 대해 나열된 제한 사항을 살펴보고 암시 적 클래스에 적합하지 않은 경우를 생각해 보겠습니다 .

  1. "유형이 값 클래스가 아닌 공개, val 매개 변수가 정확히 하나 인 기본 생성자 만 있어야합니다." 따라서 래핑하는 클래스 자체가 값 클래스 인 경우를 implicit class래퍼로 사용할 수 없지만 다음과 같이 할 수 있습니다.

    // wrapped class
    class Meters(val value: Int) extends AnyVal { ... }
    
    // wrapper
    class RichMeters(val value: Int) extends AnyVal { ... }
    
    object RichMeters { 
      implicit def wrap(m: Meter) = new RichMeter(m.value)
    }
    

    래퍼에 암시 적 매개 변수도있는 경우 해당 매개 변수를 메서드 선언으로 이동할 수 있습니다. Ie 대신

    implicit class RichFoo[T](foo: Foo[T])(implicit ord: Ordering[T]) {
      def bar(otherFoo: Foo[T]) = // something using ord
    }
    

    당신은 가지고

    implicit class RichFoo[T](foo: Foo[T]) extends AnyVal {
      def bar(otherFoo: Foo[T])(implicit ord: Ordering[T]) = // something using ord
    }
    
  2. "특수 유형 매개 변수가 없을 수 있습니다." 특수한 유형 매개 변수가있는 클래스를 래핑 할 때 래퍼를 특수화 할 수 있습니다.

  3. "중첩 또는 로컬 클래스, 특성 또는 객체가 없을 수 있습니다."다시 말하지만, 랩퍼를 구현하는 데 유용 할 수 있습니다.
  4. " equals또는 hashCode메소드를 정의 할 수 없습니다 ." 암시 적 클래스에도 equals/hashCode.
  5. "최상위 클래스이거나 정적으로 액세스 할 수있는 개체의 구성원이어야합니다."이것은 또한 일반적으로 암시 적 클래스를 정의하지만 필수는 아닙니다.
  6. "defs는 구성원으로 만 가질 수 있습니다. 특히 lazy vals, vars 또는 vals를 구성원으로 가질 수 없습니다." vars 또는 lazy vals에 대한 현명한 사용 사례를 생각할 수는 없지만 암시 적 클래스는 모든 것을 가질 수 있습니다 .
  7. "다른 클래스에 의해 확장 될 수 없습니다." 다시 말하지만, 암시 적 클래스는 확장 될 수 있지만 그럴만 한 이유가 없을 것입니다.

또한 암시 적 클래스를 값 클래스로 만들면 리플렉션을 사용하여 코드의 일부 동작을 변경할 수 있지만 리플렉션은 일반적으로 암시 적 클래스를 볼 수 없습니다.

암시 적 클래스가 이러한 제한을 모두 충족한다면 값 클래스로 만들지 않을 이유를 생각할 수 없습니다.


값 클래스암시 적 클래스를 혼동하고 있다고 생각 합니다. 향상을 위해 암시 적 클래스를 정의 할 때 값 클래스 확장 되어야 하는 동안 거의 확장하지 않습니다 AnyVal.

참조 URL : https://stackoverflow.com/questions/14929422/should-implicit-classes-always-extend-anyval

반응형