복붙노트

[SCALA] 스칼라 : asInstanceOf [T] 및 (T O) 사이의 차이점은 무엇인가?

SCALA

스칼라 : asInstanceOf [T] 및 (T O) 사이의 차이점은 무엇인가?

나는 스칼라에서 개체를 캐스팅하는 두 가지 방법이 있다는 것을 보았다 :

foo.asInstanceOf[Bar]
(foo: Bar)

제가 시도했을 때, 나는 다른 하나는 않는 반면 asInstanceOf가 암시 적 변환을 사용하지 않는 것을 발견했다.

이러한 두 가지 방법 사이에 동작의 차이점은 무엇입니까? 그리고 어디 다른 이상을 사용하는 것이 좋습니다?

해결법

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

    1.유형 ascriptions는 암시 적 변환을 실행하는 데 사용할 수 있습니다. 예를 들어, 다음과 같은 암시 적 변환을 정의 할 수 있습니다 :

    유형 ascriptions는 암시 적 변환을 실행하는 데 사용할 수 있습니다. 예를 들어, 다음과 같은 암시 적 변환을 정의 할 수 있습니다 :

    implicit def foo(s:String):Int = s.length
    

    다음과 같이 그것의 사용을 위해 :

    scala> "hi":Int                                 
    res29: Int = 2
    

    String으로 형 지능을 돌리는 것은 일반적으로 컴파일시 타입 에러가 될 것입니다,하지만 컴파일러를 포기하기 전에하면 문제가 해결 갈 수 있도록 가능한 암시 적 변환을 검색합니다. 주어진 상황에 사용되는 특정한 암시 적 변환은 컴파일 시간에 공지되어있다.

    말할 필요도없이, 런타임 오류는 바람직하지 않다 그래서 당신은 더 나은 (asInstanceof 사용하지 않고) 형태 보증 된 방식으로 일을 지정할 수있는 정도! 당신이 asInstanceOf를 사용하여 자신을 발견하면, 아마도 일치를 사용해야합니다.

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

    2.Pelotom의 대답은 이론 꽤 좋은를 다루고, 여기 명확하게하기 위해 몇 가지 예입니다 :

    Pelotom의 대답은 이론 꽤 좋은를 다루고, 여기 명확하게하기 위해 몇 가지 예입니다 :

    def foo(x: Any) {
      println("any")
    }
    
    def foo(x: String) {
      println("string")
    }
    
    
    def main(args: Array[String]) {
      val a: Any = new Object
      val s = "string"
    
      foo(a)                       // any
      foo(s)                       // string
      foo(s: Any)                  // any
      foo(a.asInstanceOf[String])  // compiles, but ClassCastException during runtime
      foo(a: String)               // does not compile, type mismatch
    }
    

    당신이 볼 수 있듯이 유형의 귀속은 해결 disambiguations로 사용할 수 있습니다. 컴파일러가 오류를보고 할, (나중에 참조) 당신이 그것을 해결해야 때때로 그들은 확인할 수없는이 될 수 있습니다. (예처럼) 다른 경우에는 그냥 당신이 원하는하지 않는 것이는 "잘못"방법을 사용합니다. foo는의 (A : 문자열) 유형의 귀속이 캐스트 아니라는 것을 보여주는, 컴파일되지 않습니다. 컴파일러는 행복 이전 라인과 비교하지만, 오류 유형의 귀속에 다음 감지 그래서 당신은 예외를 얻을.

    당신은 또한 방법을 추가하는 경우는 확인할 수없는 모호성을 얻을 것이다

    def foo(xs: Any*) {
      println("vararg")
    }
    

    당신이 모든 PARAM 하나와 foo는 호출 할, 또는 둘 다 똑같이 좋은 것 같다으로는, 변수 인수와 함께하면 컴파일러가 결정할 수 없습니다이 경우 foo는의 첫 번째와 세 번째 호출은 컴파일되지 않습니다 => 당신에게 컴파일러를 돕기 위해 형 귀속을 사용해야합니다.

    편집은 스칼라 형의 귀속의 목적은 무엇인가?를 참조하십시오

  3. ==============================

    3.케이스 클래스와 패턴 매칭 - 스칼라에서 프로그래밍하는 것은 15 장에서 세부의 비트에서이 문제를 다루고 있습니다.

    케이스 클래스와 패턴 매칭 - 스칼라에서 프로그래밍하는 것은 15 장에서 세부의 비트에서이 문제를 다루고 있습니다.

    기본적으로 두 번째 형태는 isInstanceOf asInstanceOf 및 기능을 제공하는 패턴 매치에서 "분류 된 패턴 '로서 사용될 수있다. 비교

    if (x.isInstanceOf[String]) {
      val s = x.asInstanceOf[String]
      s.length
    } else ...
    

    def checkFoo(x: Any) = x match {
      case s: String => s.length
      case m: Int => m
      case _ => 0
    }
    

    저자는 일을의 isInstance * 방법의 상세는 패턴 매칭 스타일로 당신을 조금씩 이동하는 의도적임을 암시.

    그래도 난 시험없이 간단한 유형 캐스트에 더 효과적인지 패턴 모르겠어요.

  4. ==============================

    4.차이의 예입니다 :

    차이의 예입니다 :

    예:

    class Parent() { def method() {} }
    class Child1 extends Parent() { def method1() {} }
    class Child2 extends Parent() { def method2() {} }
    
    // we return Parent type
    def getChild1() : Parent = new Child1()
    def getChild2() : Parent = new Child2()
    def getChild()  : Child1 = new Child1()
    
    (getChild1().asInstanceOf[Child1]).method1() // OK
    (getChild1().asInstanceOf[Child2]).method2() // runtime ClassCastException
    
    (getChild1() : Child2).method2() // compile-time error
    (getChild2() : Child2).method2() // compile-time error
    (getChild() : Parent).method1() // compile-time error
    (getChild()).method()  // OK
    
    // with asInstanceOf, we can cast to anything without compile-time error
    getChild1().asInstanceOf[String] // runtime ClassCastException
    getChild1().asInstanceOf[Int] // runtime ClassCastException
    

    우리는 또한 여러 파견을 사용하여 메서드를 호출 할 수 있습니다 :

    def prt(p: Parent) = println("parent")
    def prt(ch: Child1) = println("child")
    
    prt(new Parent()) // prints "parent"
    prt((new Child1()) : Parent) // prints "parent"
    prt(new Child1()) // prints "child"
    
    prt(new Parent().asInstanceOf[Child1]) // runtime ClassCastException
    prt(new Child1().asInstanceOf[Parent]) // prints "parent"
    

    우리는 암시 적 변환을 정의 할 수 있습니다 :

    // after definition of implicit conversions
    implicit def toChild1(p: Parent) : Child1 = new Child1()
    implicit def toChild2(p: Parent) : Child2 = new Child2()
    
    (getChild1() : Child2).method2() // OK - implicit conversion to Child2 in ascription
    (getChild2() : Child2).method2() // OK - implicit conversion to Child2 in ascription
    (getChild2()).method1() // OK - implicit conversion to Child1 when calling method1()
    (getChild2()).method2() // OK - implicit conversion to Child2 when calling method2()
    (getChild2() : Parent).method() // OK - no implicit conversion
    (getChild() : Parent).method1() // OK - implicit conversion to Child1 when calling method()
    
    getChild1().asInstanceOf[Int] // still runtime ClassCastException (no implicit conversion)
    
  5. from https://stackoverflow.com/questions/3412068/what-are-the-differences-between-asinstanceoft-and-o-t-in-scala by cc-by-sa and MIT license