想象一下,我在Scala中有类Imaginary(x)和类Real(y)。有没有办法做ComplexNumber = 3 + 2i而不是做ComplexNumber = Real(3)+ Imaginary(2)?
感谢。
答案 0 :(得分:4)
3 + 2.i
是否足够?
sealed trait ComplexNumber {
val re: Int
val im: Int
}
case class Real(re: Int) extends ComplexNumber { val im: Int = 0 }
implicit class ToReal(val re: Int) extends AnyVal {
def +(that: Imaginary) = Mixed(re, that.im)
}
case class Imaginary(im: Int) extends ComplexNumber { val re: Int = 0 }
implicit class ToImaginary(val im: Int) extends AnyVal {
def i: Imaginary = Imaginary(im)
}
case class Mixed(re: Int, im: Int) extends ComplexNumber
用法:
scala> 3 + 2.i
res3: Mixed = Mixed(3,2)
答案 1 :(得分:3)
2i
表示2*i
。您无法在scala中将2*a
替换为2a
,因此您应该使用运算符*
。
case class ComplexNumber(re: Int, im: Int){
def +(that: ComplexNumber) = ComplexNumber(re + that.re, im + that.im)
def -(that: ComplexNumber) = ComplexNumber(re - that.re, im - that.im)
def *(that: ComplexNumber) = ComplexNumber(re*that.re - im*that.im, re*that.im + im*that.re)
}
implicit def intToComplec(i: Int): ComplexNumber = ComplexNumber(i, 0)
object I extends ComplexNumber(0, 1)
用法:
scala> 3 + 2*I
res0: ComplexNumber = ComplexNumber(3,2)
scala> 4 - I
res1: ComplexNumber = ComplexNumber(4,-1)
答案 2 :(得分:2)
小心点。请记住,复数的实部和虚部必须都是真实的。你能做点什么:
case class Complex(real: Real, imag: Real) {
// in here define all your arithmetic ops
}
然后你可以使用senia的隐式技巧将数字自动转换为实数,并在i
中声明一个Real
方法,将其转换为虚数。
// inside Real
def i: Complex = Complex(Real(0), this)
我只是提醒你不要过多地复杂代码,只是为了可爱的语法。 Complex(a, b)
很好很清楚。如果你想创建一个解析器,请随意,但我会为String
值保留,并让代码成为代码。
答案 3 :(得分:1)
不,这是不可能的。编译器的词法分析阶段“拥有”数字字符串的后缀,例如f
(Float
),d
(Double
)和l
({{ 1}})并且这种表示法没有可扩展性。
您可能想要考虑使用新的字符串插值机制来注释常量。您必须接受解析它们和“标志”,如果您愿意(您的Long
),则必须在前缀位置使用。这会给你这样的东西:
i
我不了解新编译器中宏的功能,但也许您可以在编译时完成解析,这样就无法在运行时尝试处理格式错误的值。
这种方法(无论是编译时还是运行时解析)都是灵活的(只要您可以按照您所接受的格式进行调整),但它显然与人们在数学文本中使用的符号不符。