21장 implicit conversions and parameters - codeport/scala GitHub Wiki

21장 Implicit Conversions/Parameters

도입

타인의 코드 혹은 library를 쓰는 경우를 고려해보자

  • 보통 제공되는 모양 그대로 써야한다
  • 다른 언어의 시도는 다음과 같이 요약 가능
    • Ruby, Smalltalk: 다소 위험. 애플리케이션 전체에 영향을 미침
    • C# 3.0: static extension methods
      • local 적용 가능 but method에만 적용 가능. 변경된 인터페이스로 객체 만들 수 없음.
    • Java의 경우 extends가 거의 유일
      • 하지만 해당 내용을 건드리지는 못함
  • 스칼라는 implicite type conversion/parameter를 활용해
    • 사소한 내용은 생략하고, 관심사에 집중할 수 있도록 해줌

Swing 예제

ActionListener actionListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        System.out.println("pressed!");
    }
};//Java

Implicit Parameter와 First Class Function을 활용하여

좀 더 신선한 사례없을까

Rule!

implicit def는 다음과 같은 규칙을 갖는다

  1. Marking Rule

  2. Scope Rule

    • 해당 메서드가 동일 namespace상에 있어 바로 호출 가능해야 함
    • Companion object: import 과정이 필요하지 않음
      • Comp
    • single identifier rule이라고도 하지만 굳이 외울 필요는 없다
  3. Only one implicit: 한번만 적용

  4. Explicit 시도 후 Implicit 시도

암묵적 변환 시점

  1. Class

    • 많은 변환을 Predef에서 제공한다.
  2. Method

    • 기존 클래스 계층과 보다 매끈하게 사르르~ 통합

    • DSL 지원을 위해 사용됨

      Map(1 -> "one", 2 -> "two", 3 -> "three")

      소스코드를 확인해 보면

        object Predef {
          class ArrowAssoc[A](x: A) { //...
      
  3. Parameter (list)

    • 아래의 implicit parameters 참고

implicit parameters

  • 부가적인 인자를 parameter list에 모아 논 curry함수를 생각해 보자.

    • 예: someMethod(require1,require2)(optional1,optional2)
    • 맨 뒤 파라미터 리스트만 가능한가? (아마도 누군가가 정리해 주겠지)
      • (complier가 implicit을 사용하면 마지막 파라미터로 인식하는 것 같습니다.)
  • 책 내용 요약

    • argument리스트에 위치
    • 파라미터 각각에 적용되는게 아니라 리스트 전체에 적용
    • 흔한 타입말고 레어한 타입을 implicit로 설정
  • 용어정리

    1. implicit parameter list
      • with implicit val

ViewBounds

def maxList[T <% Ordered[T]](elements: List[T]): T = 
  elements match {
	case List() =>
	  throw new IllegalArgumentException("empty list!")
	case List(x) => x
	case x :: rest =>
	  val maxRest = maxList(rest)  // (orderer) is implicit
	  if (x > maxRest) x           // orderer(x) is implicit
	  else maxRest
  }

여러 개의 변환이 적용될 때

  • 2.7 이전: implicit conversion 적용 대상이 여러 개일 경우 ambiguity 예외 발생
  • 2.8 이후: 보다 가까운/구체적인 변환을 선택하여 적용

implicits 디버깅하기

  1. implicit conversion 함수를 직접 호출하여 테스트

    scala> val chars: List[Char] = wrapString("xyz")

    :19: error: type mismatch;

    found : scala.collection.immutable.WrappedString

    required: List[Char] val chars: List[Char] = wrapString("xyz")

  2. 컴파일러 옵션(-Xprint:typer) 활용

    • implicit conversion 내역을 직접 확인할 수 있다.
⚠️ **GitHub.com Fallback** ⚠️