[SCALA] 스칼라 : asInstanceOf [T] 및 (T O) 사이의 차이점은 무엇인가?
SCALA스칼라 : asInstanceOf [T] 및 (T O) 사이의 차이점은 무엇인가?
나는 스칼라에서 개체를 캐스팅하는 두 가지 방법이 있다는 것을 보았다 :
foo.asInstanceOf[Bar]
(foo: Bar)
제가 시도했을 때, 나는 다른 하나는 않는 반면 asInstanceOf가 암시 적 변환을 사용하지 않는 것을 발견했다.
이러한 두 가지 방법 사이에 동작의 차이점은 무엇입니까? 그리고 어디 다른 이상을 사용하는 것이 좋습니다?
해결법
-
==============================
1.유형 ascriptions는 암시 적 변환을 실행하는 데 사용할 수 있습니다. 예를 들어, 다음과 같은 암시 적 변환을 정의 할 수 있습니다 :
유형 ascriptions는 암시 적 변환을 실행하는 데 사용할 수 있습니다. 예를 들어, 다음과 같은 암시 적 변환을 정의 할 수 있습니다 :
implicit def foo(s:String):Int = s.length
다음과 같이 그것의 사용을 위해 :
scala> "hi":Int res29: Int = 2
String으로 형 지능을 돌리는 것은 일반적으로 컴파일시 타입 에러가 될 것입니다,하지만 컴파일러를 포기하기 전에하면 문제가 해결 갈 수 있도록 가능한 암시 적 변환을 검색합니다. 주어진 상황에 사용되는 특정한 암시 적 변환은 컴파일 시간에 공지되어있다.
말할 필요도없이, 런타임 오류는 바람직하지 않다 그래서 당신은 더 나은 (asInstanceof 사용하지 않고) 형태 보증 된 방식으로 일을 지정할 수있는 정도! 당신이 asInstanceOf를 사용하여 자신을 발견하면, 아마도 일치를 사용해야합니다.
-
==============================
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.케이스 클래스와 패턴 매칭 - 스칼라에서 프로그래밍하는 것은 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.차이의 예입니다 :
차이의 예입니다 :
예:
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)
from https://stackoverflow.com/questions/3412068/what-are-the-differences-between-asinstanceoft-and-o-t-in-scala by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] SparkContext, JavaSparkContext,는 SqlContext 및 SparkSession의 차이? (0) | 2019.11.19 |
---|---|
[SCALA] 나는 두 개 이상의 목록 스칼라에서 함께 압축 할 수 있습니까? (0) | 2019.11.19 |
[SCALA] 목록에서 고유 항목을 찾는 방법 스칼라 (0) | 2019.11.19 |
[SCALA] 더 나은 문자열 스칼라에 서식 (0) | 2019.11.19 |
[SCALA] 스칼라 메모이 제이션 : 어떻게이 스칼라 메모 작동합니까? (0) | 2019.11.19 |