2011-02-05 16 views
2

は、ここで私はがやりたいものです(警告:先に非常に壊れスカラ):明らかにオブジェクトをインスタンス化する前にオブジェクトのメンバを参照できますか?

def assignToFour[X](x : X, y : Something[X]) = x.y = 4 

class M { 
    var m = 0; 
} 

val em = new M 
assignToFour(em, M.m) 
em.m == 4 

、まったく動作しませんが、私は、私が参照できるようになりますパターンを探しています抽象的にインスタンスのメンバーに、次にある時点で、そのインスタンスに実際のインスタンスでアクセスします。

これはJavaの場合は反射を使用しますが、反射はうまくいっていますし、Javaよりもはるかに少ないScalaがより良い選択肢になることを期待しています。

答えて

1

あなたが特定の種類に依存しないように、structural typesを使用する(ただし、何も更新するプロパティの名前を渡すことができるというある程度の柔軟性が失われていない)ことができます:構造タイプであるが

def assignToFour(x:{var y:Int}) = x.y = 4 
+1

私はこの質問が 'y'を抽象化する方法を望んでいたと思います。 –

+3

@Ben、はい、まさに、しかし、私は涼しい構造型がどういうことができるのか忘れてしまいました。 – Malvolio

+0

など:私はまだScalaを学んでいます。この構文についてもう少し詳しく説明できますか(または詳細へのリンク)? – Andy

3

代わりに内部で反射を使用します。

def applyWith4[X,Y](x: X)(f: X => Int => Y) = f(x)(4) 

このメソッドは、2つの引数を取ります。:ターンXと一つの機能fのいくつかのインスタンスを使用すると、関数呼び出しにそれを一般化することができますので、あなたが実際に何をしたいのか

は、いくつかのプロパティのセッターを呼び出すですXIntから一部のタイプY(これはあなたの場合はUnitになります)の関数に変換します。だから、

applyWith4(em)(_ m_=) 
4

  • はScalaのプロパティが実装されている

    は今、あなたは、生成されたセッターm_=を使用して

    applyWith4(em)(x => x.m = _) 
    

    または短いが、読みにくくバリアントで使用してそれを呼び出すことができます一組の方法として。 var mについてゲッターはm命名され、setterメソッドはm_=

  • メソッドが自動的にファーストクラスは、ここで開始

値として

  • 機能が周りに渡すことができる機能に持ち上げることができるという名前になります。

    class M { 
        var m = 0 
    } 
    
    val x = new M 
    

    xmは現在0ですが、それを変更してください...

    def callWithFour(fn: Int=>Unit) = fn(4) 
    

    そして、それを使用して::ここ は、その引数として関数を取り、値4でその関数を呼び出す方法です

    x.m_=が上mプロパティのセッターメソッドである
    callWithFour(x.m_=) 
    

    インスタンスx

    x.mは4になりました。

  • 関連する問題