2

我目前正在学习 Scala 编程语言(顺便说一下喜欢它),最近发现了隐式转换。所以我有我的类 Complex 和它的伴生对象。在我的伴侣对象中,我想要这些隐式转换:

    implicit def convertToComplex(x: Double) = new Complex(x, 0);
    implicit def convertToComplex(x: Int) = new Complex(x, 0);
    implicit def convertToComplex(x: Float) = new Complex(x, 0);
    implicit def convertToComplex(x: Short) = new Complex(x, 0);
    implicit def convertToComplex(x: Long) = new Complex(x, 0);

为了不使我的复数类因 +、-、* 和 / 的重载而膨胀,以添加数字类型。

所以我的问题是:

有没有更短的方法来编写带有某种语法糖的隐式转换?(我的意思是没有所有的重载......)

提前致谢。

4

3 回答 3

4

你可以做这样的事情

object ConvertComplex {
  case class Complex[T: Numeric](x: T, y: Int) {

    val nX = implicitly[Numeric[T]]

    def doSomething = nX.toInt(x) * y
    def doSomethingElse = nX.plus(x, nX.fromInt(y))
  }

  object Complex {
    implicit def convertToComplect[T: Numeric](x: T) = Complex(x, 0)
  }

}

以及测试结果:

def doSomething[T: Numeric](x: Complex[T]) = x.doSomething
def doSomethingElse[T: Numeric](x: Complex[T]) = x.doSomething

val double = 1: Double    //> double  : Double = 1.0
val int = 1: Int          //> int  : Int = 1
val float = 1: Float      //> float  : Float = 1.0
val short = 1: Short      //> short  : Short = 1
val long = 1: Long        //> long  : Long = 1

doSomething(double)       //> res0: Int = 0
doSomething(int)          //> res1: Int = 0
doSomething(float)        //> res2: Int = 0
doSomething(short)        //> res3: Int = 0
doSomething(long)         //> res4: Int = 0

doSomethingElse(double)   //> res5: Double = 1.0
doSomethingElse(int)      //> res6: Int = 1
doSomethingElse(float)    //> res7: Float = 1.0
doSomethingElse(short)    //> res8: Short = 1
doSomethingElse(long)     //> res9: Long = 1
于 2013-03-07T23:15:38.467 回答
3

你需要Integral而不是Numeric如果你想Complex用 method /

这是一个几乎完成的解决方案:

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.math.Integral

class Complex[T: Integral](val real: T, val imag: T) {
  import Integral.Implicits._
  def +(that: Complex[T]) = Complex(real+that.real, imag+that.imag)
  def -(that: Complex[T]) = Complex(real-that.real, imag-that.imag)
  def *(that: Complex[T]) = Complex(real*that.real - imag*that.imag, real*that.imag+imag*that.real)
  def /(that: Complex[T]) = {
    val d = that.real*that.real + that.imag*that.imag
    Complex((real*that.real + imag*that.imag)/d, (-real*that.imag+imag*that.real)/d)
  }
  override def toString: String = imag.signum match {
    case 1  => "" + real + "+" + imag +"i"
    case -1 => "" + real + "" + imag + "i"
    case _  => "" + real
  }
}

object Complex {
  import Integral.Implicits._
  def apply[T: Integral](real: T, imag: T): Complex[T] = new Complex[T](real, imag)
  object i extends Complex[Byte](0.toByte, 1.toByte)
  implicit class Real2Imag[T](val imag: T) {
    def *(v: i.type)(implicit ig: Integral[T]) = Complex(ig.zero, imag)
  }
  implicit def promote[U, V](c: Complex[U])(implicit ev: U => V, il: Integral[V]) =
    Complex(ev(c.real), ev(c.imag))
  implicit def real2complex[T: Integral](real: T) = Complex(real, implicitly[Integral[T]].zero)
  implicit val doubleIsIntegral = scala.math.Numeric.DoubleAsIfIntegral
}

// Exiting paste mode, now interpreting.

warning: there were 2 feature warnings; re-run with -feature for details
import scala.math.Integral
defined class Complex
defined object Complex

scala> import Complex._
import Complex._

scala> val c1 = 3 + 4*i
c1: Complex[Int] = 3+4i

scala> val c2 = 3.0 + 4.0*i
c2: Complex[Double] = 3.0+4.0i

scala> val c3 = c1/c2
c3: Complex[Double] = 1.0

scala> val c4 = 3 - 4*i
c4: Complex[Int] = 3-4i

scala> val c5 = c2*c4
c5: Complex[Double] = 25.0

你可以这样写你的pow方法(注意如何生成Complex一个):

  def pow(n: Int): Complex[T] = {
    val one = Complex[T](implicitly[Integral[T]].one, implicitly[Integral[T]].zero)
    Iterator.iterate(one)(_*this).drop(n).next
  }

scala> i.pow(2)
res5: Complex[Byte] = -1

scala> i.pow(10)
res6: Complex[Byte] = -1

scala> (1+1*i).pow(4)
res7: Complex[Int] = -4

scala> (1+1*i).pow(5)
res8: Complex[Int] = -4-4i
于 2013-03-08T01:07:29.777 回答
0

就在这里。我假设这个Complex类有Double参数。然后,您可以一次性编写隐式转换。

implicit def doubleToComplex[T <% Double](x: T): Complex = new Complex(x, 0)
于 2013-03-08T20:57:06.220 回答