首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

我如何在惯用的Kotlin中“包装”这个不太“by lazy”的结果缓存函数调用呢?

在Kotlin中,可以使用lazy函数来实现延迟初始化和结果缓存。然而,lazy函数只能用于val属性,无法直接用于函数调用。但是我们可以通过创建一个包装函数来实现类似的效果。

首先,我们可以定义一个高阶函数cache,该函数接受一个lambda表达式作为参数,并返回一个函数类型。在内部,我们可以使用lazy函数来缓存结果,并将结果作为函数类型返回。

下面是一个示例代码:

代码语言:txt
复制
fun <T> cache(block: () -> T): () -> T {
    val lazyValue: Lazy<T> = lazy(block)
    return { lazyValue.value }
}

使用这个cache函数,我们可以将需要缓存结果的函数进行包装。例如,假设我们有一个函数expensiveOperation,它执行一些昂贵的计算,并返回结果。我们可以使用cache函数将其包装起来,以实现结果的缓存。

代码语言:txt
复制
val cachedOperation = cache { expensiveOperation() }

现在,cachedOperation就是一个函数类型,每次调用它时,都会返回缓存的结果。如果多次调用cachedOperation,实际上只会执行一次expensiveOperation,后续调用会直接返回缓存的结果。

这种方式可以在Kotlin中模拟类似于by lazy的结果缓存功能。它适用于任何需要缓存函数调用结果的场景。

对于腾讯云相关产品和产品介绍链接地址,由于不能提及具体品牌商,建议您访问腾讯云官方网站,查找相关产品和文档。腾讯云提供了丰富的云计算服务,包括计算、存储、网络等方面的产品,可以根据具体需求选择适合的产品。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Kotlin、Swift、Scala 的延迟求值

代码中,it.value 的 it 是 Lazy 类型,value 是 Lazy 的属性,我们可以通过这个属性来触发 Lazy 逻辑的运算,并且返回这个结果 —— Lazy 用作属性代理时逻辑也是如此...这两个函数,我们既可以直接传入函数引用,也可以构造一个 Lambda 表达式来包装对它们的调用。...BooleanByName 中的 valueByName 是一个函数,Scala 当中对于不修改类内部状态的无参函数通常声明成没有括号的样子,这样的函数调用时如同访问属性一样( 如代码中的 _.valueByName...Lambda 表达式包装对 returnFalse 函数的调用;后面的两个参数直接使用函数名传入,这类似于 Kotlin 当中的函数引用的用法。...,跨平台才是最牛逼的,加油 Kotlin,我等着 Android Studio 5.0 写 iOS 呢(zZZ)。

1.8K20

Kotlin|这些隐藏的内存陷阱,你应该熟记于心

内联很好,但别太长 inline ,翻译过来为 内联 ,在 Kotlin 中,一般建议用于 高阶函数 中,目的是用来弥补其运行时的 额外开销。...(就是这么倔强) 上面我们提到了,内联是会将代码移动到调用处,降低 一层栈帧,但这个性能提升真的大吗? 再仔细想想,移动到调用处,移动到调用处。这是什么概念呢?...假设我们某个方法里代码只有两行(我想不会有人会某个方法只有一行吧),这个方法又被好几处调用,内联是提高了调用性能,毕竟节省了一次栈帧,再加上方法行数少(暂时抛弃虚拟机优化这个底层条件)。...推荐示例 我们在文章最开始提到了,Kotlin inline ,一般建议用于 高阶函数(lambda) 中。为什么呢?...参阅 Kotlin代码检查在美团的探索与实践 关于我 我是 Petterp ,一个三流 Kotlin 使用者,如果本文对你有所帮助,欢迎点赞评论收藏,你的支持是我持续创作的最大鼓励!

82330
  • Kotlin 的 Property Delegate 与 Swift 的 Property Wrapper

    更神奇的是,Kotlin-Native 居然支持了与 Objective-C 的互调用,进而也就相当于某种意义上支持了与 Swift 的互调用,这下它们就更亲密了。 Swift:我不是我没有别瞎说。...实际上,如果我们把 SharedPreference 看成是类似内存一样的存储空间,那么为什么我们不能像读写内存中的变量那样轻松自在呢?...需要等到 Activity 的 onCreate 调用之后才会初始化,因此 lazy 就显得非常必要了。...说来也有趣,在它的设计文档中还特意 "diss" 了 Kotlin 的属性代理的语法设计:单独为了属性代理搞了一个 by 关键字实在是有些重,在其他场景下也不太好复用,于是 Swift 的属性包装器采用了与...这个 projectedValue 实际上也是一个属性包装器,它的类型是 Binding,Binding 这个属性包装器的作用比较直接,类似于我们前面介绍 Kotlin 的属性代理时提到的

    5.3K20

    Kotlin的5种单例模式

    我靠一个object 关键字就完成相同的功能?一行代码? Kotlin的对象声明 学习了Kotlin的小伙伴肯定知道,在Kotlin中类没有静态方法。...} } } 上述代码中,我们可以发现在Kotlin实现中,我们让其主构造函数私有化并自定义了其属性访问器,其余内容大同小异。 如果有小伙伴不清楚Kotlin构造函数的使用方式。...Lazy是接受一个 lambda 并返回一个 Lazy 实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用...大家还是看这个 ---高阶函数 委托属性 如果你了解以上知识点,我们直接来看Lazy的内部实现。...其具体逻辑与Java的双重检验是类似的。 到里这里其实大家还是肯定有疑问,我这里只是实例化了SynchronizedLazyImpl对象,并没有进行值的获取,它是怎么拿到高阶函数的返回值呢?。

    1.2K00

    【Vue原理】Computed - 源码版

    1、保存 computed 计算函数 2、保存计算结果 3、控制缓存计算结果是否有效 看下 Watcher 源码构造函数 function Watcher(vm, expOrFn, options)...把用户设置的 computed-getter,存放到 watcher.getter 中,用于后面的计算 2、watcher.value 存放计算结果,但是这里有个条件,因为 lazy 的原因,不会新建实例并马上读取值...,传入 lazy 没错,作用是把计算结果缓存起来,而不是每次使用都要重新计算 而这里呢,还把 lazy 赋值给了 dirty,为什么呢?...包装返回 get 函数 重点就在第三点,为什么重要?...2、computed 被读取,createComputedGetter 包装的函数触发,第一次会进行计算 computed-watcher.evaluted 被调用,进而 computed-watcher.get

    1.1K50

    Kotlin下的5种单例模式

    我靠一个object 关键字就完成相同的功能?一行代码? Kotlin的对象声明 学习了Kotlin的小伙伴肯定知道,在Kotlin中类没有静态方法。...} } } 上述代码中,我们可以发现在Kotlin实现中,我们让其主构造函数私有化并自定义了其属性访问器,其余内容大同小异。 如果有小伙伴不清楚Kotlin构造函数的使用方式。...Lazy是接受一个 lambda 并返回一个 Lazy 实例的函数,返回的实例可以作为实现延迟属性的委托: 第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用...大家还是看这个 ---高阶函数 委托属性 如果你了解以上知识点,我们直接来看Lazy的内部实现。...其具体逻辑与Java的双重检验是类似的。 到里这里其实大家还是肯定有疑问,我这里只是实例化了SynchronizedLazyImpl对象,并没有进行值的获取,它是怎么拿到高阶函数的返回值呢?。

    1.4K10

    深入浅出Kotlin协程

    仅仅从概念层面去讲也可以总结出几条: 因为某些协程库的实现使用了任务分发(比如Kotlin),于是可以在协程函数(也就是Kotlin coroutine中的suspend方法)中无限递归调用自身而不会栈溢出...对于这样的方法,我们无法在常规方法中直接调用,只能在声明了接收suspend lambda原型的方法中才能调用,如内置的coroutine-builder: launch,async,当然也可以在另一个...假设我们现在有个同步调用doSomething,做了一些很高深和耗时的计算比方说把传入的整形加上42然后返回,然后我们还需要对计算结果进一步的处理, 形如test函数中的做法 fun doSomething...CPS不过是换了一种写法来把对返回值的处理放到函数调用的过程中了,那么在Kotlin协程中,它扮演的角色如何呢?...ThreadSafeHeapNode类型的队列,内部存储结构为数组,多废话一句,tailrec 这个关键在kotlin中是为了告诉编译器要对该函数进行尾递归优化,也即是不要分配多余的栈空间,直接复用前一个方法调用的

    11.6K113

    【翻译】Kotlin致简代码之路

    我们不应该制造出那些一看到函数名称就感觉意图不明显,发生非期望中的隐藏的变化。但是副作用到底是什么问题呢?...实际上,这是 Kotlin 中一种惯用的写代码方式。在这个方面, Kotlin 鼓励使用不可变的变量、数据结构以及集合。因此,结果就是这会让你的代码更加健壮并且易于理解。...我们可以直接在这个列表上调用 filter() 方法(并不像 Java 8 中那样要求使用 stream() 方法)。...没必要再调用一个 getter 方法。 val id = design.id design.id = 2 //编译错误。非可变属性。 这个 copy() 方法在函数编程中特别的实用。...大部分情况这只会暴露出 Java 语言的缺陷。辛运的是,这些惯用方法和模式都很好的集成在 Kotlin 中了。详细信息可以参考我博客里关于 Kotlin 习惯用法的文章。

    1.4K30

    【Android进阶】Kotlin面向对象

    引言 在Kotlin中,我可以声明普通类、数据类、静态类,它也有抽象类和接口,其中abstract关键字只能作用在普通类。...类和对象 普通类 Kotlin中的普通类通过class关键字定义,这种类默认都是final类型的,无法被继承。...没有真正增加代码,扩展的内容不参与多态,调用的哪个就是哪个。但如果子类的扩展覆盖了父类的扩展,如果用子类去调用该函数,会使用子类的扩展函数。总之,谁调用就使用谁的扩展。...} 该属性第一次用到时会调用lazy{}代码块中的内容,并缓存到内存中,第二次就直接从内存中获取到值了。...Kotlin和Java互调 Kotlin可以支持不写类直接写函数,而Java调用Kotlin这样的函数式,需要写文件名Kt.函数名即可。

    53030

    Kotlin Vocabulary | Kotlin 内建代理

    接下来就让我们开始了解这些内建代理的使用,以及其内部的实现原理。 lazy() lazy() 函数是一个属性代理,它可以帮您在第一次访问属性时对它们进行惰性初始化。这个函数在创建昂贵对象时十分有用。...,SynchronizedLazyImpl 的 getValue() 函数就会被调用,这个函数将会在一个 synchronized 块中对属性进行初始化: override val value: T...这个类同时也实现了一个叫做 afterChange() 的函数,这个函数持有您传递给 observable 代理的 lambda 函数。 的 setter 调用,这意味着每当调用者为 address 设置一个新的值,setter 就会自动调用 afterChange() 函数,结果就会使所有的监听器都会收到有关改变的通知...观察反编译后的 Person 可以发现,Kotlin 新生成了一个继承 ObservableProperty 的类,该类中包含了我们传入 beforeChange() 函数的 lambda 表达式,setter

    1K00

    Kotlin代码检查在美团的探索与实践

    访问一个伴生对象的私有常量字段需要经过以下方法: 调用伴生对象的静态方法 调用伴生对象的实例方法 调用主类的静态方法 读取主类中的静态字段 为了访问一个常量,而多花费调用4个方法的开销,这样的Kotlin...LazyThreadSafetyMode.PUBLICATION:多个线程会同时执行,初始化属性的函数会被多次调用,但是只有第一个返回的值被当做委托属性的值。...for循环 Kotlin提供了downTo、step、until、 reversed等函数来帮助开发者更简单的使用for循环,如果单一的使用这些函数确实是方便简洁又高效,但要是将其中两个结合呢...可惜的是目前还没有解析Kotlin语法树的单独库,只能通过Kotlin编译器这个库中的相关类来解析。KLint用的是kotlin-compiler-embeddable:1.1.2-5库。...最后采用的方案是: 通过创建klintrules这个空的aar,将klint.jar放入assets中; 修改KLint代码实现从assets中读取klint.jar; 项目依赖klintrulesaar

    1.5K40

    【Android进阶】Kotlin笔记

    现在如果我们要实现eval函数来计算抽象语法树的最终结果,我们发现,始终需要一个else来收尾,因为Expr可能还有其他实现类,可能既不是Sum又不是Num,尽管代码里根本没有其他实现类。...我们上面编写的类也是,你可以调用CountingSet传入不同的Collection实现,不同的是我们提供了一个默认值。...) } 这一次我们提供了一个lazy方法,Lazy方法会返回我们的委托人LazyDelegate,因为Kotlin官方就为一些自带的委托封装了方法,可能是Kotlin社区惯用的编码规范,确实,这样好看一些...Kotlin根本没有静态这一说,Kotlin代替静态的办法一个是object,一个是顶层函数。但这俩都不适用于静态工厂,因为静态工厂经常要访问类中的私有成员。 伴生对象是用来干这些的。...但是,别忘了Kotlin中的命名参数,上面的例子本可以用命名参数更加方便的解决。 class Person constructor( name: String, age: Int?

    71820

    Android开发必备知识:为什么说Kotlin值得一试

    从外观上,乍一看还以为是 Scala,我曾经琢磨着把 Scala 作为我的下一门语言,不过想想用 Scala 来干嘛呢,我又不做大数据,而它又太复杂了o(╯□╰)o 用Kotlin创建一个数据类 ?...最初是在 intelliJ 的源码中看到 Kotlin 的,那时候 Kotlin 的版本还不太稳定,所以源码总是编译不过,真是要抓狂啊,还骂『什么破玩意儿!为什么又出来新语言了?...反过来在 Java 中调用 Kotlin 也毫无压力,官方文档C alling Kotlin from Java 对于常见的情况作了比较详细的阐述,这里就不再赘述。...还是举个例子,我需要在 Activity 当中创建一个 View 的引用,通常我们在 Java 代码中这么写: ? 在 Kotlin 当中呢? ? 每次用 aTextView 都要加俩!...因为这段代码是 inline 的,最终编译时是要编译到调用它的代码块中,这时候T的类型实际上是确定的,因而 Kotlin 通过 reified 这个关键字告诉编译器,T 这个参数可不只是个摆设,我要把它当实际类型来用呢

    1.2K90

    开源 | 如何写一个好用的 JetPack Compose 状态页组件

    那我直接去 Loading 中触发请求逻辑? 可以做,但是怎么做呢?虽然我知道这样能做,但是具体该怎么封装好呢? 于是有没有一个简便的,封装好的组件供我参考或者拿来就用呢?...但是 compose 与 view 的配置项怎么设置呢? 因为两者的配置肯定不同,那么有没有一种方式也能统一这两者的设置。 为了便于设置,我定义了一个 StateX 的静态类。...但是 Kotlin 支持扩展函数与方法,这样,通过唯一的 StateX 入口,我们便可以在相应的 compose 与 view 的model中增加基于 StateX 的扩展函数,便于增加配置项。..._internalState 变量,其代表当前状态,并且使用 State 包装,这样当我们调用 showXxx() 方法显示具体状态时,我们内部就会对相应的状态以及附带的 value 进行更新,从而...,并且定义了加载数据的方法, 在Ui部分,我们使用了一个 rememberState 这个方法缓存当前的 state 状态,在这里方法中我们还可以初始化 state 的部分回调,并且启用了加载数据,这将触发

    81420

    Android--利用APT+kotlinpoet实现组件化开发Router机制

    ,可以在settings.gradle中为module重新设置新路径 我将libbase放入了新建文件夹lib_comm下: 修改settings.gradle配置: include ':libbase...和path,还有RouterMeta包装类,最后生成的Map的对应关系如下图: 上面的是一个group对应一个IPathRouter生成类,IPathRouter是一个接口,我们会在Router组件中定义出来...,下面是一个path对应一个RouterMeta包装类 这两个Map,用来替换我们上一篇中,自己要手动导入Activity关系的Map,看到这你也许会懵,没关系往下看接口的定义 1.新建Router...第二步我们需要往两个Map中存入映射关系,来获取跳转时对应的类,现在把它们定义出来 /** * 映射关系缓存 * Created by aruba on 2021/11/23. */ object...(path) { // 缓存中没有,就利用RouterPath生成类实例化后,调用cacheInRouterMetaByPath加入 (CacheMap.RouterPathByGroup

    95720

    Coroutine(协程)(一)

    当然,可以使用更合乎惯用法的方式重写,使用 runBlocking 来包装 main 函数的执行: fun main() = runBlocking { // 开始执行主协程 GlobalScope.launch...在协程内部可以像普通函数一样使用挂起函数, 不过其额外特性是,同样可以使用其他挂起函数(如本例中的 delay)来挂起协程的执行。...为啥呢?因为一段协程代码必须协作才能被取消 协程的取消是 协作 的。一段协程代码必须协作才能被取消。 所有 kotlinx.coroutines 中的 挂起函数 都是 可被取消的 。...任何尝试在 finally 块中调用挂起函数的行为都会抛出 CancellationException。...将 start 参数设置为 CoroutineStart.LAZY] 而变为惰性的。 在这个模式下,只有结果通过 await 获取的时候协程才会启动,或者在 Job 的 start 函数调用的时候。

    85410

    破解 Kotlin 协程(2) - 协程启动篇

    start,还特别纳闷为啥我开的线程不启动呢。...说实话,这个线程的 start 的设计其实是很奇怪的,不过我理解设计者们,毕竟当年还有 stop 可以用,结果他们很快发现设计 stop 就是一个错误,因为不安全而在 JDK 1.1 就废弃,称得上是最短命的...当然,我们说 Kotlin 是一门跨平台的语言,因此上述代码还可以运行在 JavaScript 环境中,例如 Nodejs。...在 Nodejs 中,Kotlin 协程的默认调度器则并没有实现线程的切换,输出结果也会略有不同,这样似乎更符合 JavaScript 的执行逻辑。 更多调度器的话题,我们后续还会进一步讨论。...2.2 LAZY LAZY 是懒汉式启动, launch 后并不会有任何调度行为,协程体也自然不会进入执行状态,直到我们需要它执行的时候。这其实就有点儿费解了,什么叫我们需要它执行的时候呢?

    1K30

    如何使用 Ktor 快速开发 Web 项目

    Ktor 是一个由 Kotlin 团队打造的 Web 框架,可用于创建异步、高性能和轻量级的 Web 服务器,并使用 Kotlin 惯用的 API 构建非阻塞的多平台 Web 客户端。...Ktor Server.png 在 main() 中调用 embeddedServer 来启动 Ktor 应用 运行一个 EngineMain 的 main() 并使用 HOCON application.conf...module 中添加 shadow 插件和输出 jar 包名称以及 jar 包的入口 Main 函数: plugins { id 'java' id 'kotlin' id 'com.github.johnrengelman.shadow...例子 以 RxCache 为例,本文会介绍使用 Ktor 开发一个 Local Cache 的 browser(浏览器),用于读取磁盘缓存中的数据。...因此,我使用 RxCache 存储埋点的数据,所以需要一个浏览器的程序来查看本地的埋点数据。

    5.4K10
    领券