我目前正在学习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);
为了不使用+, - ,*和/的重载来增加我的复数类,以便添加数字类型。
所以我的问题是:
是否有一种较短的方法来编写带有一些语法糖的隐式转换? (我的意思是没有所有重载...)
提前致谢。
答案 0 :(得分:3)
你可以做这样的事情
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
答案 1 :(得分:3)
如果您希望Integral
使用方法Numeric
,则需要Complex
而不是/
。
这是一个几乎完成的解决方案:
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
答案 2 :(得分:0)
是的,有。我假设Complex
类有Double
个参数。然后你可以一次写一个隐式转换。
implicit def doubleToComplex[T <% Double](x: T): Complex = new Complex(x, 0)