복붙노트

[SCALA] 암시 적 변환 대 형 클래스

SCALA

암시 적 변환 대 형 클래스

스칼라, 우리는 기존 또는 새로운 유형을 개조하기 위해 적어도 두 가지 방법을 사용할 수 있습니다. 우리가 int를 정량화 할 수있는 무언가를 표현한다고 가정. 우리는 다음과 같은 특성을 정의 할 수 있습니다.

trait Quantifiable{ def quantify: Int }

그리고 우리는 예를 정량화하는 암시 적 변환을 사용할 수 있습니다 문자열과리스트.

implicit def string2quant(s: String) = new Quantifiable{ 
  def quantify = s.size 
}
implicit def list2quantifiable[A](l: List[A]) = new Quantifiable{ 
  val quantify = l.size 
}

다음을 가져온 후, 우리는 문자열과 목록에서의 메소드 정량화를 호출 할 수 있습니다. 정량화 목록의 길이를 저장하는 것을 참고, 그래서 정량화 후속 호출에 목록의 고가의 통과를 방지 할 수 있습니다.

대안은 "감시"정량화 [A]의 상태는, 어떤 타입 A 정량 할 수 있는지를 정의하는 것이다.

trait Quantified[A] { def quantify(a: A): Int }

우리는 다음 문자열과 목록 곳이 형 클래스의 인스턴스를 제공합니다.

implicit val stringQuantifiable = new Quantified[String] {
  def quantify(s: String) = s.size 
}

우리가 다음 인수를 정량화 할 필요가있는 방법을 작성하는 경우, 우리는 쓰기 :

def sumQuantities[A](as: List[A])(implicit ev: Quantified[A]) = 
  as.map(ev.quantify).sum

또는 상황에 맞는 구문을 결합하여 :

def sumQuantities[A: Quantified](as: List[A]) = 
  as.map(implicitly[Quantified[A]].quantify).sum

이제 질문은 온다. 어떻게 그 두 개념 사이에서 결정 할 수 있습니까?

내가 지금까지 발견했습니다.

타입 클래스

암시 적 변환

현재 하나 (또는 ​​그 이상) 나는 다른 이상을 선호하는 이유는 두 개념 문제 사이의 차이를 설명 사용 사례 (들). 또한 두 개념의 본질과 서로 간의 관계를 설명하는 것은 심지어 예를하지 않고, 좋은 것입니다.

해결법

  1. ==============================

    1.내가 스칼라에서 깊이에서 내 자료를 복제하고 싶지 않지만, 나는 그것의 가치는 해당 유형의 클래스 / 유형 특성이 무한히 더 유연 지적 생각합니다.

    내가 스칼라에서 깊이에서 내 자료를 복제하고 싶지 않지만, 나는 그것의 가치는 해당 유형의 클래스 / 유형 특성이 무한히 더 유연 지적 생각합니다.

    def foo[T: TypeClass](t: T) = ...
    

    기본 타입 클래스에 대한 로컬 환경을 검색 할 수있는 기능이 있습니다. 그러나, 나는 두 가지 방법 중 하나를 언제든지 기본 동작을 무시할 수 있습니다 :

    다음은 그 예이다 :

    def myMethod(): Unit = {
       // overrides default implicit for Int
       implicit object MyIntFoo extends Foo[Int] { ... }
       foo(5)
       foo(6) // These all use my overridden type class
       foo(7)(new Foo[Int] { ... }) // This one needs a different configuration
    }
    

    이 유형의 클래스가 무한히 더 유연합니다. 또 한가지 타입의 클래스 / 특성이 암시 조회 더 나은 지원한다는 것입니다.

    당신이 암시보기를 사용하는 경우 첫 번째 예에서, 컴파일러는 암시 조회를 위해 할 것입니다 :

    Function1[Int, ?]
    

    어떤 기능 1의 동반자 객체와 Int 인 동반자 개체를 볼 것이다.

    계량화가 암시 조회에 아무데도 것을 알 수 있습니다. 이 방법 당신은 패키지 오브젝트의 암시 뷰를 배치하거나 범위로 가져옵니다. 그것은 무슨 일인지 기억해야 할 더 많은 일입니다.

    반면에, 타입 클래스는 명시 적입니다. 당신은 메서드 서명에서 찾고 무엇을 참조하십시오. 당신은 또한의 암시 조회가

    Quantifiable[Int]
    

    이는 계량화의 동반자 객체와 지능의 동반자 개체에서 찾게됩니다. 당신이 그들의 동반자 개체에 기본을 제공 할 수있는 기본값과 (A MyString의 클래스와 같은) 새로운 유형을 제공 할 수는 내재적으로 검색됩니다 것을 의미한다.

    일반적으로, I 형 클래스를 사용합니다. 그들은 무한히 초기 예를 들어 더 유연합니다. 만 스칼라 래퍼와 자바 라이브러리 사이의 API 레이어를 사용하여, 당신은주의하지 않으면 심지어이 '위험'이 될 수있을 때 내가 암시 적 변환입니다 사용 놓습니다.

  2. ==============================

    2.놀이로 올 수있는 하나 개의 기준은 "느낌"등의 새로운 기능을 할 방법이다; 암시 적 변환을 사용하여, 당신은 단지 다른 방법처럼 보이게 할 수 있습니다 :

    놀이로 올 수있는 하나 개의 기준은 "느낌"등의 새로운 기능을 할 방법이다; 암시 적 변환을 사용하여, 당신은 단지 다른 방법처럼 보이게 할 수 있습니다 :

    "my string".newFeature
    

    타입 클래스를 사용하는 동안 ... 항상 외부 함수를 호출이 다음과 같이 표시됩니다

    newFeature("my string")
    

    당신이 암시 적 변환과 타입 클래스를 달성 할 수없는 한 가지가 아니라 형식의 인스턴스보다는, 유형에 속성을 추가하고있다. 당신이 사용할 수있는 형식의 인스턴스가없는 경우는 심지어 이러한 속성에 액세스 할 수 있습니다. 정규 예는 다음과 같습니다

    trait Default[T] { def value : T }
    
    implicit object DefaultInt extends Default[Int] {
      def value = 42
    }
    
    implicit def listsHaveDefault[T : Default] = new Default[List[T]] {
      def value = implicitly[Default[T]].value :: Nil
    }
    
    def default[T : Default] = implicitly[Default[T]].value
    
    scala> default[List[List[Int]]]
    resN: List[List[Int]] = List(List(42))
    

    개념이 밀접하게 관련이 있는지 또한이 예를 보여줍니다 자신의 인스턴스의 무한히 많은 생산하는 메커니즘이 없다면 타입의 클래스가 거의 유용하지 않을 것이다; 암시 적 방법 (안 틀림 변환)하지 않고, 난 단지 유한 한 많은 종류의 기본 속성이있을 수 있습니다.

  3. ==============================

    3.당신은 단지 이름의 래퍼로, 기능 응용 프로그램과 유사하여 두 기술의 차이 생각할 수 있습니다. 예를 들면 :

    당신은 단지 이름의 래퍼로, 기능 응용 프로그램과 유사하여 두 기술의 차이 생각할 수 있습니다. 예를 들면 :

    trait Foo1[A] { def foo(a: A): Int }  // analogous to A => Int
    trait Foo0    { def foo: Int }        // analogous to Int
    

    후자의 예는 이미 A. 적용되어있는 반면 이전의 캡슐화 타입 A의 함수의 인스턴스 => 지능, 당신은 패턴을 계속할 수 ...

    trait Foo2[A, B] { def foo(a: A, b: B): Int } // sort of like A => B => Int
    

    따라서 당신은 일종의 일부 인스턴스에 FOO2 [A, B]의 부분 응용 프로그램 등의 FOO1 [B] 생각할 수있다. 이것의 좋은 예는 "스칼라의 기능 종속성"로 마일 사빈에 의해 작성되었습니다.

    그래서 정말 내 요점은 원칙적으로,이다 :

  4. from https://stackoverflow.com/questions/8524878/implicit-conversion-vs-type-class by cc-by-sa and MIT license