복붙노트

[SCALA] "구조적인 세련미의 매개 변수 유형은 정제 외부에서 정의하는 추상 형식을 참조 할 수 없습니다"

SCALA

"구조적인 세련미의 매개 변수 유형은 정제 외부에서 정의하는 추상 형식을 참조 할 수 없습니다"

언제 컴파일 :

object Test extends App {
  implicit def pimp[V](xs: Seq[V]) = new {
    def dummy(x: V) = x
  }
}                                                                                                                                                                                                              

나는 얻다:

$ fsc -d aoeu go.scala
go.scala:3: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
    def dummy(x: V) = x
        ^
one error found

왜?

(스칼라 : 정말이 응답하지 않습니다 "구조적인 세련미의 매개 변수 유형은 정제 외부에서 정의하는 추상 형식을 참조 할 수 없습니다.")

해결법

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

    1.그것은 사양에 의해 허용되지 않는 것. 3.2.7 복합 유형을 참조하십시오.

    그것은 사양에 의해 허용되지 않는 것. 3.2.7 복합 유형을 참조하십시오.

    버그 1906가 고정되기 전에, 컴파일러는이 컴파일 한 것입니다 그리고 당신은 런타임에없는 방법을 얻었을 것입니다. 이 개정 19,442에 고정하고이 멋진 메시지가 이유입니다.

    문제는 왜이 허용되지 않습니다, 다음입니까?

    2007 년 스칼라 메일 링리스트 뒷면에서 질 Dubochet에서 여기에 아주 자세히 설명되어 있습니다 설명이 대략 구조 유형의 반사를 사용하고 컴파일러가 타입 정의 외부를 사용하는 경우 호출 방법을 조회하는 방법을 알고하지 않는다는 사실로 귀결 정제는 (컴파일러 ( "포주", 배열 (?)) p.getClass.getMethod에 getMethod 메소드의 두 번째 매개 변수를 채우는 방법을 미리 알 수 없습니다

    그러나 게시물 이동 모습, 그것은 귀하의 질문에 좀 더 대답 할 것이다.

    편집하다:

    목록을 안녕하세요.

    나는 구조적 입력에 관한 두 가지 질문에 대해 들었습니다 스칼라 2.6의 확장 요즘, 나는 여기에 대답하고 싶습니다.

    나는이 두 가지 질문에 대답하기 전에, 나는에 대해 얘기 할 필요가 구조적 유형의 구현.

    JVM의 형 시스템은 아주 기초적인 (그리고 자바 1.4에 해당). 그 스칼라 표현 될 수있는 많은 종류가 될 수 없음을 의미 VM의 표현. 경로 의존 유형 ( "x.y.A"), 싱글 타입 ( "a.type '), 화합물 유형 ("B와 A ") 또는 추상적 유형은 모든 종류 즉, JVM의 유형 시스템에 표시 할 수 없습니다.

    JVM 바이트 코드로 컴파일 할 수 있으려면, 스칼라 컴파일러가 변경됩니다 그들의 "삭제"를 프로그램의 스칼라 유형 (의 섹션 3.6 참조 참고). 삭제 된 유형이 VM의 유형 시스템에 표시 할 수 있으며, 의에 해당 프로그램의 유형 규율을 정의 이 프로그램은 덜하지만, 스칼라 유형 (일부 캐스트를 저장)와 함께 입력 정확한. 보조 노트, 유형이 VM에서 삭제 된 사실로 이유를 설명 유형의 동적 표현에 대한 작업 (패턴 유형에 대한 일치는) 매우 스칼라의 유형에 대한 제한 체계.

    지금까지 스칼라의 모든 유형 구조는 어떤 방법으로 삭제 될 수 있습니다. 이 구조 유형에 대한 사실이 아니다. 간단한 구조 유형 "{DEF X : VM이 허용하지 않을 것처럼 "개체"를 삭제할 수 없습니다 "지능} 있는 "X"필드를 액세스. 인터페이스 "인터페이스 X를 사용하여 {INT X {}; } " 삭제 된 유형 중 하나가 작동하지 않으므로 인스턴스는 구속 때문에 이 유형의 값은 할 수없는 그 인터페이스를 구현해야합니다 별도의 컴파일의 존재에서 수행 될 수있다. 사실 (나와 함께 곰) 어떤 회원이의 정의보다 같은 이름의 멤버를 포함 클래스 구조 유형 어디서나은 해당 구현해야 할 것이다 인터페이스. 불행하게도이 클래스는 이전에도 정의 할 수있다 구조 유형이 존재한다고 알려져있다.

    대신에, 구조적으로 규정 부재를 언급 구현 반사 전화로 완전히 VM의 타입 시스템을 우회. 에 대한 = p.x (4)를 재 기입한다 예 DEF ({X DEF (Q : INT) 지능} P F) 같은 뭔가 :

      def f(p: Object) = p.getClass.getMethod("x", Array(Int)).invoke(p, Array(4))
    

    그리고 지금 답변.

    스칼라 프로그램에서 정수 값이 이미 자주 박스된다합니다 (허용하기 "모든"입력)과 스칼라의 자신에서 그들을 언 박싱 낭비입니다 복싱 방식은 java.lang.Integer에 즉시 영향을 REBOX합니다.

    여전히 최악의, 반사 호출이 "모든"반환 형식이있는 경우, 하는 java.lang.Integer가 반환 될 때 무슨 짓을해야 하는가? 호출 된 방법 중 하나에 "INT"를 반환 할 수있다 (이 경우는되어야 언 박싱과 스칼라 상자로 reboxed) 또는이 반환 될 수 있습니다 그대로 남아 있어야하는 java.lang.Integer.

    대신 우리는 자바에 스칼라 자신의 복싱 방식을 변경하기로 결정했다. 그만큼 앞의 두 문제는 단순히 사라집니다. 일부 성능 관련 최적화 우리가 스칼라의 복싱 방식으로했다합니다 (사전 계산 가장 일반적인 숫자의 박스 형태) 쉽게 Java를 사용했다 너무 권투. 결국, 자바 권투를 사용하여도 조금보다 더 빨리했다 우리 자신의 계획.

    추상 형이고 매개 변수 유형은 추상적 인 유형으로 정의 구조적 정제의 범위 내에 정의에는 문제가 없다 어느 한 쪽:   DEF ({DEF X [T (T : T)} 지능 P) F = p.xInt 이 예에서 우리는 것입니다 인스턴스가 "P"로 "F"에 전달 알고 반드시 "X (t : 개체)"로 소거 "X [T (t T)"를 정의한다. 그만큼 조회 후 제대로 지워 유형에 이루어집니다 :   . DEF F (p : 개체) = p.getClass.getMethod ( "X", 어레이 (개체))를 호출하여 (p, 배열 (새 java.lang.Integer의 (4)))

    그러나 만약 구조 상세 검색의 범위를 외부에서 추상 형식 구조 방법의 매개 변수를 정의하는 데 사용됩니다, 모든 나누기 :   DEF [T] F (p {DEF X (t : T) 지능} t : T) = p.x (t) "F"가 호출 될 때, "T"는 예를 들어, 모든 유형의 인스턴스화 할 수 있습니다 :   F [지능 (DEF {X (t : INT) = t}, 4)   F [상관 (DEF {X (t : 없음) = 5}, 4) 첫 번째 경우에 대한 조회는 "getMethod 메소드 ("X "로했을 어레이 (INT)) "및 초"getMethod 메소드 ( "X", 어레이 (개체)) ", 및 본문에 생성하는 하나 알 수있는 방법이 없습니다 "F": "p.x (t)".

    몸의 ' "F"내부의 독특한 "getMethod 메소드"호출을 정의 할 수 있도록하려면 "T"의 인스턴스는 같은 "F"로 전달 된 객체를 필요로 "P"매개 변수는 "모든"을 삭제 "t"의 유형이있다. 이것은 일 것 클래스 '의 유형은 회원이 방법에 따라 달라 변환 이 클래스의 인스턴스는 프로그램에 사용됩니다. 그리고 이것은 뭔가 우리는 확실히 싶지 않아 (별도 수행 할 수 없습니다 편집).

    스칼라 유형을 런타임을 지원하는 경우 또는 하나에 사용할 수 이 문제를 해결한다. 언젠가 ...

    하지만 지금은, 구조 방법의 매개 변수에 대한 추상적 인 유형을 사용하여 형식은 간단하게 금지되어 있습니다.

    진정으로, 질.

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

    2.곧이 게시 한 후 문제를 발견 : 내가 대신 익명 클래스를 사용하는 명명 된 클래스를 정의해야합니다. (여전히 비록 추론의 더 나은 설명을 듣고 싶어요.)

    곧이 게시 한 후 문제를 발견 : 내가 대신 익명 클래스를 사용하는 명명 된 클래스를 정의해야합니다. (여전히 비록 추론의 더 나은 설명을 듣고 싶어요.)

    object Test extends App {
      case class G[V](xs: Seq[V]) {
        def dummy(x: V) = x
      }
      implicit def pimp[V](xs: Seq[V]) = G(xs)
    }                                                                                                                                                                                                              
    

    공장.

  3. from https://stackoverflow.com/questions/7830731/parameter-type-in-structural-refinement-may-not-refer-to-an-abstract-type-defin by cc-by-sa and MIT license