2017-05-29 14 views
4

DBアクセスのためにSlickを使用するテストスイートがあります。このスイートの一部のテストはDBにアクセスし、一部のテストはアクセスしません。 マイスイートは、効果的にスイートの実行の開始時にDataBaseDefを初期化暗黙的な値は、暗黙的なメソッドのパラメータ値として使用すると遅延値でもかまいませんか?

implicit val db = DB.getDB

を持っています。この値は、いくつかのメソッドでは暗黙のパラメータ値として使用されます。私が変更された場合は今

override def afterAll():Unit={ 
    db.close() 
    super.afterAll() 
    } 

: はまた、それがスイートの実行の最後にdbを閉じafterAll()を持って implicit lazy val db = DB.getDB その後、正確に何が起こるのだろうか?

DBを使用しないテストのみを実行すると、接続は初期化されず、afterAll()では接続を終了しようとしますが、この場合は問題があります。私は実行しようとしましたがエラーは発生せず、例外もスローされませんでした...

私の知識の知識は、私が怠け者と組み合わせて理解するのを助けるのに十分ではありません。

答えて

7

次に正確にはどうなりますか?

値は最初にアクセスされるまで初期化されません。

それでも接続を終了しようとしていますが、これには問題があります ケース?

あなたがdb.close()にアクセスすると、それはまず、それが前に接続を閉じるにDB.getDbを呼び出しますを意味し、値を初期化します。つまり、あなたは意図していませんでしたが、接続はまだ初期化されてすぐに閉じられるため、例外が表示されません。

+0

あなたは正しいです。私は質問を投稿した後でもっと思ったし、それは私にはっきりと分かりました。 まだ、メソッド呼び出しで暗黙的なパラメータ値の発見に 'lazy'修飾子が及ぼす影響を明確にしたいと思います。あなたはこれを手伝ってもらえますか? –

+0

または私は安全に標準の規則を引き継ぐことができます:これに関して仕様上何も言及されていない場合、レイジーはこれに関して何の効果もありませんか? –

+0

@AlexanderArendar呼び出されているメソッドで必要とされる '暗黙のlazy val'がある場合、その値を実体化します。あなたの場合、それはDB接続を作成することを意味します。 –

1

受け入れられた回答に追加するには、コンパイル時に暗黙的に解決されることを指摘したいと思いますが、vallazy valdefは実行時のみに影響します。

あなたは暗黙的として識別子を定義した場合、それはあなたが与えられた型の暗黙の値へのアクセスを持っているコンパイラを教えてくれますので、このような暗黙のパラメータを必要とする任意の方法は、それを使用します。逆に、指定された型の暗黙の識別子を宣言しないと、その型の値を必要とするメソッドへの呼び出しはコンパイラエラーをスローします。しかし、いったんコードがコンパイルされると、もう暗黙の必要はありません(スコープによっては、関連する識別子への明示的な参照に置き換えられています)。

さて、それはだ場合ランタイムで、暗黙の識別子が呼び出されたとき、それは定義をインスタンス化してメモ化することができますいずれかのように、それはvalだ場合、それは、標準のルールでインスタンス化され、インスタンス化および使用方法でメモ化lazy valであるか、それがdefであればそれぞれの使用でインスタンス化されます。暗黙的なパラメータであったという事実は、インスタンス化ルールに影響を与えません。

+0

有用で詳細な解明のためのCyrille感謝。 –

関連する問題