복붙노트

[SCALA] 스칼라 - 제네릭의 모든 대 밑줄

SCALA

스칼라 - 제네릭의 모든 대 밑줄

스칼라에서 다음 제네릭 정의 사이의 서로 다른 무엇입니까 :

class Foo[T <: List[_]]

class Bar[T <: List[Any]]

내 직감은 거의 동일하지만 후자의 것을하는 것이 더 명시 나를 알려줍니다. 어디서 경우 이전 컴파일을 찾는하고 있지만, 후자는하지 않습니다 만, 정확한 차이에 내 손가락을 넣어 수 없습니다.

감사!

편집하다:

나는 혼합으로 서로를 던질 수 있습니까?

class Baz[T <: List[_ <: Any]]

해결법

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

    1.OK, 나는 대신 댓글 게시, 나는 그것에 내 걸릴 있어야한다 생각. 죄송합니다, 당신이 TL을 원하는 경우, 길이 될 것입니다; DR은 끝으로 건너 뜁니다.

    OK, 나는 대신 댓글 게시, 나는 그것에 내 걸릴 있어야한다 생각. 죄송합니다, 당신이 TL을 원하는 경우, 길이 될 것입니다; DR은 끝으로 건너 뜁니다.

    랜달 슐츠가 말했듯이, 여기 _ 실존 유형에 대한 속기입니다. 즉,

    class Foo[T <: List[_]]
    

    속기를위한이다

    class Foo[T <: List[Z] forSome { type Z }]
    

    참고 그 랜달 Shulz의 대답은 (전체 공개 : 나는 그것을 지적 예스퍼 Nordenberg에 잘못도이 게시물의 이전 버전에 덕분에 그것을 가지고) 언급 것과는 달리이되지 같은 :

    class Foo[T <: List[Z]] forSome { type Z }
    

    도 아니다과 동일합니다 :

    class Foo[T <: List[Z forSome { type Z }]]
    

    그것은 쉽게 얻을 조심 그것은 잘못된 (내 이전 노는 쇼 등) : 랜달 Shulz의 대답에 의해 참조 된 문서의 저자가 잘못된 자신 (주석 참조), 나중에 고정을 얻었다. 이 기사에 내 주요 문제는 예 표시에, existentials의 사용은 입력 문제에서 우리를 저장하도록되어 있다는 것입니다,하지만하지 않습니다. 코드를 확인하고 compileAndRun (helloWorldVM ( "테스트")) 또는 compileAndRun (intVM (42)) 컴파일하려고 이동합니다. 네, 컴파일되지 않습니다. 단순히에 compileAndRun 일반적인 만들기 코드 컴파일을 만들 것, 그것은 훨씬 더 간단 할 것이다. 즉, 그것은 아마 existentials과 그들이 (자신이 코멘트에서 인정 저자는 기사는 "정리하는 작업이 필요합니다"것을)에 대한 좋은 대해 배울 수있는 가장 좋은 글이 아니다.

    오히려이 글을 읽는 것이 좋습니다 그래서 : http://www.artima.com/scalazine/articles/scalas_type_system.html을, 특히 절은 "실존 적 유형"과 "자바와 스칼라의 차이"라는.

    이 문서에서 얻을 hould 것이 중요한 점은 비 공변 유형을 다룰 때 existentials이 (떨어져 일반적인 자바 클래스를 처리 할 수있는에서) 유용 것입니다. 다음은 예이다.

    case class Greets[T]( private val name: T ) {
      def hello() { println("Hello " + name) }
      def getName: T = name
    }
    

    이 클래스는 (참고도입니다 불변) 일반적이지만, 우리는 내가 접견의 인스턴스를 얻는 경우에 그래서 나는 항상 호출 할 수 있어야, 그 인사는 정말 (getName 달리) 형식 매개 변수의 사용을하지 않습니다 볼 수 있습니다 그것은, 어떤 T입니다. 나는 접견 인스턴스를 가진 메서드를 정의 할 바로 그 안녕하세요 메소드를 호출하면,이 시도해 볼 수도 있습니다 :

    def sayHi1( g: Greets[T] ) { g.hello() } // Does not compile
    

    T 아무데도 여기에 나오는대로 과연,이 컴파일되지 않습니다.

    확인 후,하자이 방법은 일반적인합니다

    def sayHi2[T]( g: Greets[T] ) { g.hello() }
    sayHi2( Greets("John"))
    sayHi2( Greets('Jack))
    

    위대한이 작동합니다. 우리는 또한 여기 existentials을 사용할 수 있습니다 :

    def sayHi3( g: Greets[_] ) { g.hello() }
    sayHi3( Greets("John"))
    sayHi3( Greets('Jack))
    

    너무 작동합니다. 전부 그래서, (sayHi2 같이) 여기 형식 매개 변수를 통해 (sayHi3에서와 같은) 존재를 사용에서 실제 혜택이 없습니다.

    접견 다른 제네릭 클래스에 대한 형식 매개 변수로 자신을 표시하는 경우에는이 변경됩니다. 우리가 목록에서 (다른 T와) 접견의 여러 인스턴스를 저장하려는 예에 의해 말. 해 보자:

    val greets1: Greets[String] = Greets("John")
    val greets2: Greets[Symbol] = Greets('Jack)
    val greetsList1: List[Greets[Any]] = List( greets1, greets2 ) // Does not compile
    

    접견은 불변이기 때문에 접견은 [문자열]과 접견 [심볼]을 접견 [모든] 문자열과 기호가 모두 어떤을 확장하더라도로서 취급 할 수 없도록 마지막 줄은 컴파일되지 않습니다.

    OK,의는 속기 표기법을 사용하여, 실존 적으로 해보자 _ :

    val greetsList2: List[Greets[_]] = List( greets1, greets2 ) // Compiles fine, yeah
    

    이 벌금을 컴파일, 예상대로 당신은 할 수 있습니다 :

    greetsSet foreach (_.hello)
    

    이제 접견는 불변이기 때문에 우리가 처음에 유형 검사 문제가 있었다 이유는 것을 기억하십시오. 그것이 공변 클래스로 전환 된 경우 (클래스 접견은 [+ T])는 다음 모든 상자 밖으로 일 것이다 우리는 필요 existentials을하지 않을 것입니다.

    그래서 요약하면, existentials은 일반적인 불변 클래스를 처리하는 데 유용하지만, 일반 클래스가 다른 제네릭 클래스에 대한 형식 매개 변수로 자신을 표시 할 필요가없는 경우, 기회는 당신이 existentials 필요 단순히 형식 매개 변수를 추가하지 않는 것이 있습니다 에 당신의 방법을 작동합니다

    이제 관련, 특정 질문에 (마지막에, 나도 알아!) 돌아와

    class Foo[T <: List[_]]
    

    목록 공변이기 때문에,이 모든 의도 그냥 말과 같은 목적을위한 것입니다 :

    class Foo[T <: List[Any]]
    

    이 경우 그래서, 하나 표기법을 사용하는 것은 정말 스타일의 문제입니다.

    당신이 세트 목록을 대체 할 경우, 상황이 변경 :

    class Foo[T <: Set[_]]
    

    설정은 불변이며, 따라서 우리는 내 예제의 접견 클래스와 같은 상황에 있습니다. 따라서 정말 위는 매우 다르다

    class Foo[T <: Set[Any]]
    
  2. ==============================

    2.전자는 코드 유형이 무엇인지하거나 제한 할 필요가 없습니다 실존 유형에 대한 속기입니다 :

    전자는 코드 유형이 무엇인지하거나 제한 할 필요가 없습니다 실존 유형에 대한 속기입니다 :

    class Foo[T <: List[Z forSome { type Z }]]
    

    이 양식은 목록의 요소의 형태가 클래스 푸 아닌 목록의 요소 유형 없음입니다 특별히 말한다 두 번째 형태에 알 수 있다고 말한다.

    스칼라의 실존 적 유형에 대한 간략한 설명 블로그 기사를 체크 아웃 (편집 :이 링크는 이제 죽었다, 스냅 샷 archive.org에서 확인할 수 있습니다)

  3. from https://stackoverflow.com/questions/15186520/scala-any-vs-underscore-in-generics by cc-by-sa and MIT license