2017-05-17 3 views
0

のための暗黙のインスタンス変数を設定し、それぞれの方法では、暗黙的なメソッドのパラメータの使用s私は、ユーティリティ・メソッドの束とScalaのオブジェクトを持っているScalaのオブジェクト

object MyObject { 
def a(implicit s:String) = ??? 
def b(implicit s:String) = ??? 
def c(implicit s:String) = ??? 
} 

になり、私は私が必要とするという事実が好きではありません。各パラメータリストのimplicit s:String。変数sを1回だけ設定する方法はありますか(オブジェクトに初めてアクセスするとき)。クラスの場合、私は次のようなことをします:

class MyClass(implicit s:String) { 
def a() = ??? 
def b() = ??? 
def c() = ??? 
} 

答えて

5

短い答えは「いいえ、できません」です。

なぜですか? sは変数ではないため、パラメータです。したがって、コンパイル時に実行時にある時点(たとえば最初のアクセス時)に設定されず、(暗黙的であるため)解決されます。

コードの一部にMyObject.aを書き込むと、コンパイラは現在のスコープ内に暗黙的にStringの定義があるかどうかをチェックし、その定義をsに使用します。

コードの別の部分でaを使用すると、そのスコープ内の暗黙の定義が使用されますが、これは非常に異なる場合があります。

これはコンパイル時に検証されるため、実行時にメソッドにアクセスするときとは関係ありません(アクセス時には、回避可能なimplicitsがある場合はsのランタイム値が変更される可能性があります。 )。

いつも同じ定義をsに使用する場合は、単にこの定義をオブジェクトに入れないでください。または暗黙のようにそれをインポートします。

object MyObject { 
    implicit def myImplicitString: String = ??? //first possibility 
    import MyImplicits.stringImplicit //second possibility, if stringImplicit is indeed defined as implicit 
} 

一番下の行は、パラメータとして暗黙的に渡したくない場合は、あなたがスコープでそれを持っている必要があり、あり、そして、あなたの範囲がobjectているので、それがなければなりません常に同じです。

しかし、classを使用すると何が問題になりますか?多くの通話を変更することなく、暗黙のパラメータを繰り返すことを避けるために、MyObject.aの代わりにnew MyClass().a、またはcase classと定義するとMyCaseClass().aを使用します。オブジェクトに他のフィールドがある場合は、インスタンス化時のオーバーヘッドを最小限に抑えるために、それらのフィールドをクラスのコンパニオンオブジェクトに入れることができます。

関連する問題