简体   繁体   English

从Scala中的类创建Singleton对象

[英]Creating Singleton Object from a class in Scala

When I was playing with the Scala, I couldn't figure out something. 当我与Scala一起玩时,我无法弄清楚什么。 Maybe I am doing completely wrong. 也许我做错了。

I was trying with Rational Example and Complex Example but I couldn't find a way to use operations like R*3/5 and 1/2*R 我正在尝试使用Rational Example和Complex Example,但找不到使用R * 3/5和1/2 * R之类的操作的方法

here is the complex numbers example I am working on 这是我正在处理的复数示例

class Complex(val real : Int, val img : Int){

  def this(real: Int) = this(real, 0)

  def *(that : Complex) = {
    val realPart = this.real * that.real + -(this.img * that.img)
    val imgPart = this.real * that.img + this.img * that.real
    new Complex(realPart, imgPart)
  }

  override def toString = this.real  + "+" + this.img + "i"

}

object Complex {
  def apply(real : Int, img : Int) = new Complex(real, img)
  def apply(real : Int) = new Complex(real)
}

object ComplexNumbers {

  def main(args: Array[String]) {

    import ComplexConversions._
    println(Complex(1,2)) // 1+2i
    println(I*2) //0+2i
    println(2*I) //0+2i
  }
}

Well I have tried to create an object I 好吧,我尝试创建一个对象

object I{
  def apply() = new Complex(0,1)  

  def *(that : Complex) = {
    val realPart = 0 * that.real + -(1 * that.img)
    val imgPart = 0 * that.img + 1 * that.real
    new Complex(realPart, imgPart)
  }
}

but it did work for the I*2. 但它确实适用于I * 2。 but I have problems for 2*I. 但是我有2 * I的问题。 How can I reach the result that I want? 如何获得想要的结果?

When you call " I * 2 ", scala looks for a method named " * " on the class of I , and finds it. 当您调用“ I * 2 ”时,scala在I的类上寻找一个名为“ * ”的方法并找到它。

When you call " 2 * I ", scala looks for a method named " * " on the class of 2 (which is Int ), and cannot find one. 当您调用“ 2 * I ”时,scala在2类(即Int )上查找名为“ * ”的方法,但找不到一个。

Even though Int is defined externally, you can add this method to it in Scala via the "implicit conversion" mechanism. 即使Int是在外部定义的,也可以通过“隐式转换”机制在Scala中向其添加此方法。 This is covered briefly in the "implicits" example and in more detail elsewhere, eg here 这在“隐式”示例中进行简要介绍, 其他地方(例如此处)进行了更详细的介绍

Try adding some code like the following to your "Complex" object: 尝试将类似以下的代码添加到“ Complex”对象中:

object Complex {
  implicit class IntOps(x: Int) {
    def *(y: Complex) = y * x
  }
}

You'll also need to declare I as a val, rather than an Object for this to work: 您还需要将I声明为val,而不是将Object声明为:

val I = Complex(0, 1)

(or add an implicit method like class Complex { def *(i: I) = ... } , but that's much uglier) (或添加一个类似class Complex { def *(i: I) = ... }的隐式方法,但这要难看得多)

(I assume by Complex Example, you mean this ?) (我以“复杂示例”为假设,您的意思是这个 ?)


Working code: 工作代码:

class Complex(val real : Int, val img : Int){

  def this(real: Int) = this(real, 0)

  def *(that : Complex) = {
    val realPart = this.real * that.real + -(this.img * that.img)
    val imgPart = this.real * that.img + this.img * that.real
    new Complex(realPart, imgPart)
  }

  override def toString = this.real  + "+" + this.img + "i"

}

object Complex {
  def apply(real : Int, img : Int) = new Complex(real, img)
  def apply(real : Int) = new Complex(real)

  val I = Complex(0, 1)

  implicit def toComplex(x: Int): Complex = new Complex(x)
}

object ComplexNumbers {

  def main(args: Array[String]) {

    import Complex._

    println(Complex(1,2)) // 1+2i
    println(I*2) //0+2i
    println(2*I) //0+2i
  }
}

If you want to be able to use 2*I , you will need to add a new * override for the Int class (since * is really a method of the class Int , meaning 2*I is really 2.*(I) ). 如果你希望能够使用2*I ,你将需要添加一个新的*覆盖的Int类(因为*是真正的类的方法Int ,这意味着2*I真的是2.*(I)

You can accomplish this with an implicit class: 您可以使用隐式类来完成此操作:

scala> case class myInt(i: Int){
     | def mult(that: Int): myInt = myInt(that * i)
     | }
defined class myInt

scala> implicit class intOverride(i: Int){
     |     def *(that: myInt): myInt = that.mult(i)
     | }
defined class intOverride

scala> val a = myInt(2)
a: myInt = myInt(2)

scala> 2 * a
res1: myInt = myInt(4)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM