2013-11-03 5 views
7

pow에 대한 ** 구문을 매우 좋아합니다. 많은 언어 (예 : Python)로 제공됩니다.스칼라를위한`**`파워 연산자 생성하기?

Scala 'base'코드를 수정하지 않고 이것을 Scala에 도입 할 수 있습니까? Int에서

내 시도 하나 :

import scala.math.pow 
implicit class PowerInt(i: Int) { 
    def `**`(n: Int, b: Int): Int = pow(n, b).intValue 
} 

이 (가 IDEone에 실패 참조)이 나를 위해 작동

+7

주'이 **'도'^'올바른 우선 순위를 (즉, 이유가 없습니다 이유는 다음 stdlib 그것을 포함하지 않습니다). '4 * 5 ** 3'는'4 * (5 ** 3)'이 아니라'(4 * 5) ** 3'입니다. – sschaef

+0

스칼라는 구문 분석 방법을 비 LL (1) 문법으로 변경할 수 있습니다. 예 : C++이 여러 개의'>''< '를 어떻게 처리하는지보십시오. –

답변

11

: (문제 # 1 펑은 문제 # 2 확장 anyval, 복식에 정의) (또한 아무 소용이 methodName로에있는 그 역 따옴표를 가진에 없다?)

import scala.math.pow 

object RichIntt { 

    implicit class PowerInt(val i:Double) extends AnyVal { 
    def ** (exp:Double):Double = pow(i,exp) 
    } 

    def main(args:Array[String]) 
    { 
    println(5**6) 
    } 

} 
+1

이것은 꽤 멋집니다. –

12

이 답변은 아직 FO 2 년 늦게 r 다른 사람들의 이익 인정 된 대답이 불필요하게 AnyVal에서 연장되었다는 것을 지적하고 싶습니다.

원래 답변에서 수정해야하는 사소한 버그가 있습니다. def ** 메소드는 단 하나의 매개 변수 만 필요합니다. 즉, 기본 코드가 이미 생성자에서 전달되고 두 코드가 원래 코드와 같이 전달되는 지수입니다. 그 고정하고있는 역 따옴표 결과를 제거 : here를 볼 때 예상대로 작동

import scala.math.pow 
implicit class PowerInt(i: Int) { 
    def ** (b: Int): Int = pow(i, b).intValue 
} 

. 거기에 호출되는 메소드가 정의되지 않은 경우

스칼라 컴파일러는 IntPowerInt A를 캐스팅합니다. 그래서 AnyVal에서 확장 할 필요가 없습니다.

장면 뒤에서 스칼라는 생성자의 인수 유형이 형 변환되는 객체의 유형과 동일한 암시 적 클래스를 찾습니다. 객체는 하나의 유형 만 가질 수 있으므로 암시 적 클래스는 생성자에서 둘 이상의 인수를 가질 수 없습니다. 게다가 동일한 생성자 유형을 가진 두 개의 암시 적 클래스를 정의하는 경우 해당 함수의 고유 한 서명이 있는지 확인하십시오. 그렇지 않으면 Scala는 어떤 클래스를 형변환할지 모르기 때문에 모호성에 대해 불평 할 것입니다.

1

Numeric typeclass 사용하여 좀 더 일반적인 솔루션을 만들 수있는 방법이 있습니다 :

implicit class PowerOp[T: Numeric](value: T) { 
    import Numeric.Implicits._ 
    import scala.math.pow 

    def **(power: T): Double = pow(value.toDouble(), power.toDouble()) 
}