Map.withDefaultをざっと見てみると、「get」がどこで定義されているのかわかりませんでした。デフォルトでは明らかに1をメモ化していないように見えますが、「get」の一部の実装では舞台裏でメモ化できるようです。
基本的に、私が知りたいのは、1回だけ実行する必要がある計算がある場合、デフォルトのマップはそれを何度も実行するのか、それとも1回だけ実行するのかということです。
Map.withDefaultをざっと見てみると、「get」がどこで定義されているのかわかりませんでした。デフォルトでは明らかに1をメモ化していないように見えますが、「get」の一部の実装では舞台裏でメモ化できるようです。
基本的に、私が知りたいのは、1回だけ実行する必要がある計算がある場合、デフォルトのマップはそれを何度も実行するのか、それとも1回だけ実行するのかということです。
問題ない。私は長い間、非常によく似たトリックを行ってきました。
scala> :paste
// Entering paste mode (ctrl-D to finish)
def someFunction ( s : String ) = {
println("someFunction called")
s.size
}
val someFunctionMemoized : String => Int
= new collection.mutable.HashMap[String, Int] {
override def default ( key : String )
= {
val value = someFunction(key)
update(key, value)
value
}
}
// Exiting paste mode, now interpreting.
someFunction: (s: String)Int
someFunctionMemoized: String => Int = Map()
scala> someFunctionMemoized("abc")
someFunction called
res0: Int = 3
scala> someFunctionMemoized("abc")
res1: Int = 3
質問をした直後に、関数にミューテーターが埋め込まれているreplをチェックインできることに気付きました。
scala> val map = new Map.WithDefault[String, String](Map(), {string => { println(string); string } } )
map: Map.WithDefault[String,String] = Map()
scala> map("key")
key
res5: String = key
scala> map("key")
key
res6: String = key
scala> import scala.collection.mutable
import scala.collection.mutable
scala> val mmap = new mutable.Map.WithDefault[String, String](mutable.Map(), {string => { println(string); string } } )
mmap: scala.collection.mutable.Map.WithDefault[String,String] = Map()
scala> mmap("key")
key
res7: String = key
scala> mmap("key")
key
res8: String = key
したがって、答えは次のとおりです。いいえ。あなた自身を転がしてください。