Función de memorización en Kotlin

Tengo una class existente con un método de instancia buildHierarchyUncached cuya firma se puede encontrar a continuación.

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

Me gustaría proporcionar una function pública buildHiearchy que sea una versión modificada de buildHierarchyUncached. Puedo acercarme a lo que quiero:

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

Que se puede llamar así:

 hierarchyService.buildHiearchy(businessDate) 

Utilizando:

 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) } ) } } 

Me gustaría poder declarar la function memorada como una function en lugar de una propiedad, que no es un gran problema, aunque creo que ayuda a la legibilidad. Me gusta esto:

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

pero eso no comstack: "No coincide el tipo. Nodo requerido. Se ha encontrado memoize".

Además, ¿por qué no comstack esto?

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

Por la naturaleza del problema, necesita un campo de class para almacenar su caching (el valor en caching o un object de caching o un delegado). Entonces debes declarar un val en la class en alguna parte, ya que las funciones no pueden hacer eso.

Tenga en count que cuando declara su valor buildHiearchy , obtiene dos cosas en una: almacena un object Memoize<..>(..) en un campo de class y obtiene la function invoke() (declarada en otro lugar, pero aún así …) . Sé de ninguna manera que pueda declarar una function y get el almacenamiento de campo sin syntax adicional.

El fragment de código usa syntax obsoleta. Arregle así (sin paréntesis):

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

La siguiente solución funciona para funciones de argumento único. Si desea crear una versión en caching de la bar funciones, simplemente lo declara así:

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

La implementación almacena el caching en un cierre para que no tenga que colocarlo en una class dedicada:

 fun <X, R> makeFunctionCache(fn: (X) -> R): (X) -> R { val cache: MutableMap<X, R> = HashMap() return { cache.getOrPut(it, { fn(it) }) } } 
  • Gradle no importará una dependencia bintray, pero no lanza ningún error
  • ¿Tiene Kotlin un equivalente a opciones opcionales de envoltura implícita en Swift?
  • quiero get un resultado de la list diferente
  • Referencia no resuelta de la function de secuencia de Kotlin
  • Anotación @JsonValue en la propiedad de valor de la class enum de Kotlin
  • kotlin, cómo agregar la function de extensión al object compañero de class ya definido
  • En Kotlin cuando uso Kovenant Promise.of (value) a veces goteo excepciones
  • ¿Cuándo debería usar let {} y cuando simplemente! = Null
  • El service está creando una nueva instancia de mediaplayer
  • Referencia no resuelta: campo en Kotlin
  • ¿Es posible express kotlin 'con' método equivalente en Scala?