복붙노트

[SCALA] 자바의 수의 스칼라 동등한

SCALA

자바의 수의 스칼라 동등한

나는 수치 도메인 유형에 대한 유형 계층 구조를 구축하기 위해 노력하고 있습니다. 예를 들면 년은 (는 숫자입니다) int로는, 몇 퍼센트가 나는 값에 toInt 또는 toDouble를 호출 할 수 있도록 계층 구조를 필요 번호 등입니다 더블,입니다.

그러나, 원시 숫자 유형에 대한 스칼라 유형 계층은 AnyVal 제외하고 공통 조상이 없습니다. 이것은 내가 필요로하는에 {INT, 더블} 기능이 포함되어 있지 않습니다.

내가 찾을 수있는 가장 가까운 유형은 일부 컴파일러 속임수 주로 존재하는 것 같다 숫자 [T]입니다.

자바에서 모든 숫자는 (임의의 정밀 것을 포함) 수에서 유래. 어떻게 하나의 인터페이스를 정의 않습니다 스칼라에서 객체의 수치 유형에 대한 충족시켜 그?

나는 현재 오리 입력으로 해킹하고 있습니다 :

Any {
  def toInt: Int
  def toDouble: Double
}

이는 단지 장황한되지 않지만 초래 반사 비용을 런타임. 거기에 아무것도 더 나은가요?

해결법

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

    1.숫자 [T]는 당신이 찾고있는 정확하게이다. 여기 갈 스칼라의 방법은 유형 클래스 (숫자와 같은 즉 일)입니다.

    숫자 [T]는 당신이 찾고있는 정확하게이다. 여기 갈 스칼라의 방법은 유형 클래스 (숫자와 같은 즉 일)입니다.

    대신에

    def foo(x: java.lang.Number) = x.doubleValue
    

    중 하나를 쓰기

    def foo[T](x: T)(implicit n: Numeric[T]) = n.toDouble(x)
    def foo[T : Numeric](x: T) = implicitly[Numeric[T]].toDouble(x)
    

    여기서 두 번째는 (거의) 아무것도하지만 문법 설탕입니다.

    숫자의 인스턴스를 호출하면 표현이 더 복잡 할 때 동작이 서투른 될 수 있습니다 필요한 때마다 작성. 이것을 완화하기 위해, 숫자는 수학 연산을 작성하는 일반적인 방법으로 T 보강 암시 mkNumericOps 변환을 제공한다 (즉, 1 + 2보다는 n.plus (1,2)).

    사람들을 사용하기 위해서는, 단지 암시 적 숫자의 구성원을 가져옵니다

    def foo[T](x: T)(implicit n: Numeric[T]) = {
      import n._
      x.toDouble
    }
    

    때문에 수입에 대한 제한을 암시에 대한 축약 구문은 여기에 거의 바람직합니다.

    무슨 일이 일어나는가? 인수 목록이 암시 적으로 표시되어있는 경우, 컴파일러는 자동으로 암시 적 범위에 존재하는 것으로 표시되어 해당 유형의 정확히 하나 개의 값이 있으면를 필요한 유형의 값을 넣어 것입니다. 당신이 작성하는 경우

    foo(1.0)
    

    컴파일러는 자동으로 변경됩니다

    foo(1.0)(Numeric.DoubleIsFractional)
    

    두 번에 조작에 메소드 foo를 제공.

    이것의 큰 장점은 당신이 그들을 모른 채 종류의 숫자를 만들 수 있다는 것입니다. 당신이 당신에게 형 MyBigInt을 제공하는 라이브러리가 가정하자. 불행하게도 - - 개발자가이 번호를 연장하지 않았다 이제 자바 세계에 있다고 가정합니다. 당신이 할 수있는 것은 아무것도 없습니다.

    스칼라에서, 당신은 쓸 수 있습니다

    implicit object MyBigIntIsNumeric extends Numeric[MyBigInt] {
       def compare(x: MyBigInt, y: MyBigInt) = ...
       // ...
    }
    

    그리고 숫자가 지금 MyBigInt과 함께 작업 당신이하지 않았다하지만 사용하는 모든 코드 라이브러리를 변경합니다. 그래서 숫자은 당신의 프로젝트에 개인이 될 수 있으며,이 패턴은 작업을 계속합니다.

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

    2.@ gzm0에서 대답이 유형은 시간을 컴파일에서 확인할 수 있어야 정적 솔루션, 난, 런타임 타입 캐스팅 동적 솔루션을 제공

    @ gzm0에서 대답이 유형은 시간을 컴파일에서 확인할 수 있어야 정적 솔루션, 난, 런타임 타입 캐스팅 동적 솔루션을 제공

    데프 toDoubleDynamic (X : 모든) = X 일치 {      경우의 : 문자열 => s.toDouble      케이스 요 : 상위를 => jn.doubleValue ()      경우 _ => 새로운 ClassCastException를 슬로우 ( "더블 캐스팅 할 수 없습니다") }

    그것은 런타임에서 올바른 유형을 선택하는 경우 일치를 사용합니다.

  3. from https://stackoverflow.com/questions/17999409/scala-equivalent-of-javas-number by cc-by-sa and MIT license