別の式の奥深くからスカラー式に複数回アクセスするための最も簡潔でバイトコード効率の良い方法は何ですか?
次のコード(scalar4を除く)のすべての関数は、必要に応じて機能します。しかし、バイトコーダーだけが効率的なバイトコードを出力し(ISTORE 2 ILOAD 2でうまく終了しませんが)、他のバイトコーダーはそれぞれ5ダースのINVOKEを生成します。
このイディオムは、タプルの任意の部分をパラメーターとして渡す場合にも便利です。
for (a_tuple) { f(_._3, _._1) + g(_._2) } // caution NOT legal Scala
この例では、イントロは1回だけ呼び出す必要がある高価な関数を表しています。
object Hack extends App
{
@inline final def fur[T, V](x :T)(f :T => V) :V = f(x)
@inline final def pfor[T, V](x :T)(pf :PartialFunction[T, V]) = pf(x)
@inline final def cfor[T, V](x :T)(f :T => V) :V = x match { case x => f(x) }
def intro :Int = 600 // only one chance to make a first impression
def bytecoder = intro match { case __ => __ + __ / 600 }
def functional = fur(intro) (x => x + x / 600)
def partial = pfor(intro) { case __ => __ + __ / 600 }
def cased = cfor(intro) ($ => $ + $ / 600)
def optional = Some(intro).map(? => ? + ? / 600).get
def folder = Some(intro).fold(0)(? => ? + ? / 600)
// the for I wish for
def scalar4 = for(intro) (_ + _ / 600) // single underline!
println(bytecoder, functional, partial, cased, optional, folder)
}
public bytecoder()I
ALOAD 0
INVOKEVIRTUAL com/_601/hack/Hack$.intro ()I
ISTORE 1
ILOAD 1
ILOAD 1
SIPUSH 600
IDIV
IADD
ISTORE 2
ILOAD 2
IRETURN