簡體   English   中英

為Scala創建`**`power運算符?

[英]Creating `**` power operator for Scala?

我非常喜歡pow**語法,可用於許多語言(例如Python)。

是否可以將其引入Scala,而無需修改Scala“基礎”代碼?

我在Int只嘗試一次:

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

(看到它在IDEone失敗

這對我有用:(問題#1 pow在雙打中定義,問題#2擴展為anyval)(也沒有意義在方法名中有這些反引號?)

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)
  }

}

這個答案遲了2年,仍然為了其他人的利益,我想指出所接受的答案不必要地延伸到AnyVal。

只有一個小錯誤需要在原始答案中修復。 def **方法只需要一個參數,即指數作為基礎已經在構造函數中傳遞,而不是原始代碼中的兩個。 修復並刪除反引號會導致:

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

其作品如預期看到這里

只有在未定義調用的方法時,Scala編譯器才會將Int PowerInt轉換為PowerInt 這就是你不需要從AnyVal擴展的原因。

在幕后,Scala查找一個隱式類,其構造函數參數類型與轉換對象的類型相同。 由於對象只能有一個類型,因此隱式類在構造函數中不能有多個參數。 此外,如果您使用相同的構造函數類型定義兩個隱式類,請確保它們的函數具有唯一的簽名,否則Scala將不知道要轉換到哪個類並且會抱怨歧義。

有一種方法可以使用Numeric類型類使解決方案更通用:

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

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

這是我使用遞歸的解決方案(所以我不需要import scala.Math.pow ):

object RichInt {
    implicit class PowerInt(val base:Double) {
        def ** (pow:Double):Double = if (pow==0) 1 else base*(base**(pow-1))
    }

    def main(args:Array[String]){
        println(2.0**3.0) //8.0
        println(2.0**0.0) //1.0
    }  
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM