2016-02-10 9 views
5

私はインスタンスメソッドbuildHierarchyUncachedを持つ既存のクラスを持っています。このメソッドのシグネチャは下にあります。コトリンでのメモ機能

private fun buildHierarchyUncached(date: LocalDate): Node { ... } 

私はbuildHierarchyUncachedのメモ化バージョンである公共機能 buildHiearchyを提供したいと思います。私は近い私が欲しいものを得ることができます使用

hierarchyService.buildHiearchy(businessDate) 

::のように呼び出すことができます

val buildHiearchy = Memoize<LocalDate, Node>({buildHierarchy(it)}) 

class Memoize<I, O>(val func: (I) -> O): (I) -> O{ 
    val cache = hashMapOf<I, O>(); 
    override fun invoke(p1: I): O { 
    return cache.getOrPut(p1, { func(p1) }) 
    } 
} 

は私がとメモ化関数を宣言できるようにしたいと思います私はそれが可読性を助けると思うが、大したことではないプロパティの代わりに関数。このように:

fun buildHierarchy(date: LocalDate): Node = Memoize<LocalDate, Node>({ buildHierarchyUncached(it)}) 

それはコンパイルされません: "型が一致しません必要なノードが見つかりmemoizeを。。。"

また、なぜこれはコンパイルされませんか?問題の性質によって

val buildHiearchy = Memoize<LocalDate, Node>({(date) -> buildHierarchy(date)}) 
+0

コンパイラエラーのあるものについては、他の人がこのSOの質問を検索/見つけることができるように、コンパイラからのエラーメッセージを含めるといいです。 –

+0

私が得たコンパイルエラーを追加しました。 –

答えて

4

、あなたのキャッシュ(キャッシュされた値またはキャッシュオブジェクトまたはデリゲート)を格納するクラスのフィールドを必要としています。関数はそれを行うことができないので、クラスのどこかでvalを宣言しなければなりません。あなたは、クラスのフィールドにMemoize<..>(..)オブジェクトを格納し、あなたはinvoke()機能を取得する(他のどこかで宣言、それでも...):あなたのbuildHiearchy値を宣言するとき、あなたは一つに二つのことを得ること

は注意してください。私は、関数を宣言し、追加の構文なしでフィールドストレージを取得することはできません。

コードスニペットでは古い構文が使用されています。このように修正してください(かっこはありません)。

val buildHiearchy = Memoize<LocalDate, Node>({date -> buildHierarchy(date)}) 
+0

エリアスの答えはクロージャを使用しており、クラスは必要ありません。あなたのスニペットは私の二次的な質問に答えますが、私の主な質問には答えません。実際の質問をより明確にするために質問を編集しました。つまり、私はどのようにしてプロパティの代わりに関数としてメモされた関数を宣言できますか? –

+0

まあ、それは私の指摘です - あなたはどこかのフィールドなしでこのような機能を持つことはできません – voddan

1

次の解決策は、単一引数関数で機能します。あなたは、専用のクラスでそれを配置する必要がないように

val cachedBar = makeFunctionCache({ bar(it) }) 

実装店閉鎖でキャッシュ:あなたが機能barのキャッシュされたバージョンを作成したい場合は、単にこのようにそれを宣言し

fun <X, R> makeFunctionCache(fn: (X) -> R): (X) -> R { 
    val cache: MutableMap<X, R> = HashMap() 
    return { 
     cache.getOrPut(it, { fn(it) }) 
    } 
} 
+0

おそらく私の質問から明らかではなかった。しかし、私はcachedBarを次のような関数として宣言したいと思います: 'fun cachedBar(date:LocalDate):Node = makeFunctionCache ({date-> bar(date)})' –

+0

あなたの質問を修正し、正確に何をする必要がありますか?クロージャーソリューションがうまくいかない理由は明らかではありません。それは他のどのような機能のように見え、動作します。関数が実際にインターフェイスの一部である場合は違いがありますが、より多くの情報が役立つはずです。 –

関連する問題