복붙노트

[SCALA] 왜 스칼라 방법이 명시 적으로 호출은 암시 적으로 해결 될 수 있습니까?

SCALA

왜 스칼라 방법이 명시 적으로 호출은 암시 적으로 해결 될 수 있습니까?

내가 표시된 행의 주석을 해제 할 때 왜이 코드는 컴파일되지 않지만, 성공적으로 컴파일? (나는 매일 밤 스칼라 2.8을 사용하고 있습니다). 명시 적으로 string2Wrapper를 호출하면 그것은 그 시점에서 암시 적으로 사용할 수 있습니다 것으로 보인다.

class A {
  import Implicits.string2Wrapper
  def foo() {
     //string2Wrapper("A") ==> "B" // <-- uncomment
  } 
  def bar() {
    "A" ==> "B"
    "B" ==> "C"
    "C" ==> "D"
  }
  object Implicits {
    implicit def string2Wrapper(s: String) = new Wrapper(s)
    class Wrapper(s: String) {
      def ==>(s2: String) {}
    }
  }
}

편집 : 마틴 오더 스키의 의견에 대한 포인터를 포함 지금까지 답변 주셔서 감사합니다,

나는 여전히 1에서 발견에 관심이있을 것) "순환 참조 오류"의 위험은 무엇인가? 2)는 이유를 명시 적으로 호출은 어떤 차이가 있습니까?

해결법

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

    1.명시 적으로 string2Wrapper의 반환 형식이 문제를 해결 돌리는.

    명시 적으로 string2Wrapper의 반환 형식이 문제를 해결 돌리는.

    class A {
      import Implicits._
    
      def bar() {    
        "A" ==> "B"
        "B" ==> "C"
        "C" ==> "D"
      }
      object Implicits {
        implicit def string2Wrapper(s: String): Wrapper = new Wrapper(s)
        class Wrapper(s: String) {
          def ==>(s2: String) {}
        }
      }
    }
    

    바는 작동하기 전에 Implicits 정의 :

    class A {
      object Implicits {
        implicit def string2Wrapper(s: String) = new Wrapper(s)
        class Wrapper(s: String) {
          def ==>(s2: String) {}
        }
      }
    
      import Implicits._
    
      def bar() {    
        "A" ==> "B"
        "B" ==> "C"
        "C" ==> "D"
      } 
    }
    

    현재 범위 내에서 아래 정의 된 암시 적 변환에 의존해야하는 경우, 당신이 그것의 반환 유형을 주석합니다. 확신이 전에 메일 링리스트에 도달했습니다, 그리고 버그보다는 행동을 예상 할 수있다. 그러나 나는 그 순간에 그것을 찾을 수 없습니다. 나는 foo는 트리거에서 명시 적으로 호출 줄의 내용을 입력 할 때 다음 유효 줄의 반환 유형의 형식 유추를 같아요.

    최신 정보

    암시 적 방법의 몸은 암시 적 변환을 필요로하는 메소드를 호출 할 수 있습니다. 이 모두 유추 반환 형식이있는 경우, 당신은 막 다른 골목에있어. 이것은 당신의 예에 적용되지 않지만, 컴파일러는이를 감지하지 않습니다.

    이전 명시 적 호출은 암시 적 방법의 반환 형식의 형식 유추를 트리거합니다. 여기 Implicits.isValid의 논리입니다

    sym.isInitialized ||
          sym.sourceFile == null ||
          (sym.sourceFile ne context.unit.source.file) || 
          hasExplicitResultType(sym) ||
          comesBefore(sym, context.owner)
    

    업데이트 2

    이 최근의 버그가 관련 같습니다 https://lampsvn.epfl.ch/trac/scala/ticket/3373

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

    2.그냥 ooooone 야간한다면 나중에 대신 내가 어제 추가 오류 메시지를 볼 것입니다.

    그냥 ooooone 야간한다면 나중에 대신 내가 어제 추가 오류 메시지를 볼 것입니다.

    <console>:11: error: value ==> is not a member of java.lang.String
     Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type
               "A" ==> "B"
               ^
    <console>:12: error: value ==> is not a member of java.lang.String
     Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type
               "B" ==> "C"
               ^
    <console>:13: error: value ==> is not a member of java.lang.String
     Note: implicit method string2Wrapper is not applicable here because it comes after the application point and it lacks an explicit result type
               "C" ==> "D"
               ^
    
  3. ==============================

    3.먼저 객체 Implicits를 넣어 경우 작동합니다. 여러 컴파일러 패스를 만들기위한 논리 나 버그 등이 보이는; 그것은 줄을 컴파일 할 때 정말 string2Wrapper 모르게 멀리 얻을 수 있습니다 가정합니다. 내 생각 엔 실제로 암시 적으로 문자열에 정의> Implicits 컴파일 한 다음 해당 ==을 실현, 당신이 그것을 사용하는 경우, 그것은 string2Wrapper 정말 무엇인지 모르고 넘어갈 수없는 알고 있다는 것입니다.

    먼저 객체 Implicits를 넣어 경우 작동합니다. 여러 컴파일러 패스를 만들기위한 논리 나 버그 등이 보이는; 그것은 줄을 컴파일 할 때 정말 string2Wrapper 모르게 멀리 얻을 수 있습니다 가정합니다. 내 생각 엔 실제로 암시 적으로 문자열에 정의> Implicits 컴파일 한 다음 해당 ==을 실현, 당신이 그것을 사용하는 경우, 그것은 string2Wrapper 정말 무엇인지 모르고 넘어갈 수없는 알고 있다는 것입니다.

    편집 : Retronym 게시 내용에 따라, 어쩌면 그것은 "기능"이 아니라 버그. 아직 나에게 인색 한 것 같다!

  4. from https://stackoverflow.com/questions/2731185/why-does-this-explicit-call-of-a-scala-method-allow-it-to-be-implicitly-resolved by cc-by-sa and MIT license