2016-10-19 11 views
0

Scalaで遊んでいたときに、何かを理解できませんでした。たぶん私は完全に間違っています。Scalaのクラスからシングルトンオブジェクトを作成する

私は、Rational例と複雑な例をしようとしていたが、私はここに、R * 3月5日と1/2 * R

のような操作を使用する方法を見つけることができませんでしたが、私が働いている複素数の一例です

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

まあ、私は私

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

オブジェクトを作成しようとしましたが、それはI * 2のために仕事をしました。私は2 * Iの問題があります。私が望む結果にどのように到達することができますか?

答えて

4

あなたが「I * 2」を呼び出すと、ScalaはIのクラスに「*」という名前のメソッドを探し、それを見つけました。

あなたが「2 * I」を呼び出すと、Scalaは(Intある)2のクラスに「*」という名前のメソッドを探し、そしてものを見つけることができません。

Intが外部で定義されていても、このメソッドを「暗黙の変換」メカニズムを介してScalaのメソッドに追加できます。これはthe "implicits" exampleで簡単に説明されており、他の場所で詳しく説明されています。あなたの「複合」オブジェクトに次のようないくつかのコードを追加しhere

試してみてください。

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

あなたは、むしろこれを機能させるためのオブジェクトよりも、valのように私を宣言することも必要があります:

val I = Complex(0, 1) 

(またはclass Complex { def *(i: I) = ... }のような暗黙のメソッドを追加しますが、それは非常に醜いです)

(私はあなたがを意味し、複雑な例で想定します?210)


の作業コード:

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 
    } 
} 
+0

メソッドパートのルックアップについて理解しています。コードを追加しましたが、コンプレックスのように動作しないため、型の不一致エラーが発生します。 (それはI.typeと言う)? –

+0

問題は、 "オブジェクト"として "I"を宣言することによって、自身のシングルトンクラスを取得することです。これは、コンプレックスとは異なるクラスです。 「複合語を拡張する」を「I」に追加していないので、複素数でもありません。私は私の答えに完全な実例を加えました。 – Rich

2

あなたが2*Iを使用することができるようにしたい場合は(*が本当にクラスIntの方法であるため、2*Iが本当に2.*(I)ある意味、)、あなたはIntクラスに新しい*オーバーライドを追加する必要があります。あなたが暗黙のクラスでこれを達成することができます

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) 
+0

同じ溶液が、私のタイプは複雑ではないので、今、私は再び立ち往生。それをvalとして作成しようとすると、新しいComplex(0,1)になります。それはプライベートになり、私はメインからそれに到達することはできません –

+0

私の場合、 '*'オーバーライドの範囲は 'Complex'クラスの外にありますので、どのオブジェクトからでもアクセスする必要があります。 –

関連する問題