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

我如何在惯用的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

    Coroutine(协程)(一)

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

    85310

    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

    95620

    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

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

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

    1K30

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

    看完基本条件,其实也都不难,在 View 中设计一个状态页组件,大家都知道怎么做,但是 Compose 呢? 那么我们下面就开始构思一下,如何设计这个状态页组件 StateX。...那我直接去 Loading 中触发请求逻辑? 可以做,但是怎么做呢?虽然我知道这样能做,但是具体该怎么封装好呢? 于是有没有一个简便的,封装好的组件供我参考或者拿来就用呢?...但是 Kotlin 支持扩展函数与方法,这样,通过唯一的 StateX 入口,我们便可以在相应的 compose 与 view 的model中增加基于 StateX 的扩展函数,便于增加配置项。...,我们在内部保留了一个 _internalState 变量,其代表当前状态,并且使用 State 包装,这样当我们调用 showXxx() 方法显示具体状态时,我们内部就会对相应的状态以及附带的 value...,并且定义了加载数据的方法, 在Ui部分,我们使用了一个 rememberState 这个方法缓存当前的 state 状态,在这里方法中我们还可以初始化 state 的部分回调,并且启用了加载数据,这将触发

    1.1K10

    如何使用 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
    领券