2013-10-14 4 views
1

스프레이의 자석이 얼마나 쉬운 지 분명히 이해하고 있지만, FieldDefMagnet의 모든 변환과 암시는 단지 내 머리를 날려 버립니다. 여기에 sources에서 일부입니다 : 내가 전화 할 때스프레이의 FormFieldMagnet은 어떻게 작동합니까?

def formField(fdm: FieldDefMagnet): fdm.Out = fdm() 

trait FieldDefMagnet { 
    type Out 
    def apply(): Out 
} 
object FieldDefMagnet { 
    implicit def apply[T](value: T)(implicit fdm2: FieldDefMagnet2[T]) = new FieldDefMagnet { 
    type Out = fdm2.Out 
    def apply() = fdm2(value) 
    } 
} 
trait FieldDefMagnet2[T] { 
    type Out 
    def apply(value: T): Out 
} 
object FieldDefMagnet2 { 
    implicit def apply[A, B](implicit fdma: FieldDefMagnetAux[A, B]) = new FieldDefMagnet2[A] { 
    type Out = B 
    def apply(value: A) = fdma(value) 
    } 
} 

trait FieldDefMagnetAux[A, B] extends (A ⇒ B) 

그래서, 예를 들어, formField("name") scalac가 FieldDefMagnet.apply("name")에서 "name"를 래핑는하지만 어떻게 다른 implicits이 선택하고 적용?

답변

1

그렇습니다. 예를 들어 FieldDefMagnet.apply으로 시작한 다음 방법의 암시를 찾아 계속 진행합니다.

대략적으로 말하자면, FieldDefMagnet은 1) 2) 암시 적 기능으로 주석 처리 된 값과 3) 기능의 반환 유형입니다.

FieldDefMagnet2은 반환 형식에 대한 형식 멤버가있는 암시 적 기능 일뿐입니다.

FieldDefMagnetAuxOut type-member에 대한 간단한 구문을 제공합니다. 또한 같이 쓸 수있다 (그리고 어쩌면 우리는이 작업을 수행한다)이 구조는 기본적으로 대부분의 형태 인수를 추론 스칼라 컴파일러를 만드는 방법으로 형식 유추를 안내하는 데 필요한

type FieldDefMagnetAux[A, B] = FieldDefMagnet2[A] { type Out = B } 

.

"재미있는"것들은 모두 FieldDefMagnetAux에서 발생합니다. 여기서 입력 유형의 유형에 따라 해당 기능이 계산됩니다.

편집 : 행동에 그것을보고 내가`와`FieldDefMagnet2.apply`을 수행 할 때, 암시 적 FieldDefMagnetAux`가 호출되는 이해하지

formField(
    FieldDefMagnet.apply[String]("name")(
     FieldDefMagnet2.apply[String, Directive1[String]](
     FieldDefMagnetAux.forString(
      Deserializer.fromRequestUnmarshaller[spray.http.HttpForm](
      Deserializer.fromMessageUnmarshaller[spray.http.HttpForm](
       Deserializer.formUnmarshaller(
       Deserializer.UrlEncodedFormDataUnmarshaller, Deserializer.MultipartFormDataUnmarshaller))), 
      FormFieldConverter.dualModeFormFieldConverter[String](
      Deserializer.liftToSourceOption[String, String](
       Deserializer.fromFunction2Converter[String, String](Predef.conforms[String])), 
      Deserializer.liftFromEntityOptionUnmarshaller[String](
       Deserializer.liftToSourceOption[spray.http.HttpEntity, String](
       Deserializer.StringUnmarshaller))))))) 
+0

홈페이지 포인트로 확장 formField("name")의 확장을 고려 ? 'fdm2 (value)'를 호출 할 때 그것은'trait FieldDefMagnet2 [T]'에서'def apply (value : T) : Out'에 대한 명확한 호출이고 scalac은 변환으로 해결하려고 시도해서는 안됩니다 => 찾기 '암시 ​​적 def 적용 [A, B] (암시 적 fdma : FieldDefMagnetAux [A, B])'이므로이 줄을 호출 할 때? –

+0

완전한 확장을 포함하도록 내 대답을 편집했습니다. 특정 질문에 대답하려면 : 암시적인 모든 def는 인스턴스를 필요로하는 메소드보다 먼저 호출됩니다. 그것들은 "암시 적 변환"으로 해석되지 않고 암시 적 사용의보다 강력한 형태 인 "암시 적 매개 변수"로 해결됩니다. – jrudolph