Kotlin函数进阶玩法

公众号「稀有猿诉」        原文链接 More about Kotlin Functions

Kotlin中的函数是一级对象,除了常规的函数式编程以外,还支持一些非常灵活的特殊用法,可以大大增强代码的可读性和简洁性,让代码更加的优雅,在业界顶级的库如Compose中有大量的应用,今天就来学习一些,以扫清学习Compose的障碍。

Extension Functions

与传统的编程语言如C/C++,Java或者Python最大的不同就是,Kotlin对于类的扩展提供了相当灵活的方式。像Java和Python除了标准的继承方式以外,就只能用注解和Decorator。但对于Kotlin还可以用Extensions这一方式。无论是注解还是Decorator,它的使用方式还是比较笨拙的,可以明显的看出来是额外定义的函数,与原Class是没啥关系的。

比如说,对于整数来说,我们通常会有求绝对值,通常可以这样写:

fun abs(a: Int) = if (a < 0) -a else a

然后,这样使用:

val aa = abs(a)

但在Kotlin中,有更优雅的方式:

fun Int.abs() = if (this < 0) -this else this

println((-4).abs())
println(100.abs())

这就是Extension functions,这样定义了后,可以像整数类型本身定义的方法那样直接在其对象上面调用。

如何定义Extension functions

Extension functions是针对Class的,或者一个Type的,指定目标Class名字,和参数就可以了,在函数的内部this就是调用函数时的对象。

fun <ClassName>.<function name>(params...): return type {
	// this is the function's receiver, which is the object when function invoked.
	// function implementation
}

需要注意,Extension functions必须是针对Class的。

理解Extension functions

Extension functions并没什么高深和神秘的东西,它只是相当于一个static函数,接收目标Class的对象而已,比如说:

fun Shape.area(): Int = this.length * this.width

fun area(shape: Shape): Int = shape.length * shape.width

其实这两个函数是完全一样的,上面的那个Extension function其实就相当于后面的那个常规函数。只不过在函数的调用上面更加的方便,看起来更像是目标Class提供的方法一样,更优雅一些。

Extension function的作用域

Extension function并不会真的对目标Class做任何修改,它只是相当于你自己定义的一个函数。所以,它的作用域就是你定义的函数的作用域,如果你是在一个文件中定义的,那么它的作用域就是导入了这个文件的地方;如果是在一个类中的,那作用域就是这个类。

另外的问题就是,假如在多个地方定义了相同的Extension function,会发生什么呢,相同的意思就是目标Class一样,函数名字也一样,所做的事情也一样,仍是把它当成普通函数来理解就行,按照虚拟机懒惰加载的原则,应该是第一个被引用到的Extension function生效。

参考资料

  • Extension Functions in Kotlin
  • Kotlin Extension Function: How To Implement And Use It
  • 让人爱不释手的Kotlin扩展(Extensions)技术探Extensions秘与应用
  • Kotlin 扩展函数及原理
  • Kotlin 编程 #3 扩展函数(终于知道为什么 with 用 this,let 用 it)

Infix Functions

准确的来说是Infix notation,它是一种执行函数的特殊方式,并不是定义了特殊的函数。也就是说某个函数被infix修饰了后,就可以用更为简洁的方式来调用它。常规的函数执行(或者说调用)是用函数名字加上括号,括号里面是参数,比如foo(),bar(“here”)。而infix方式则可以是 参数1 函数名 参数2这种方式,也即与常规的函数调用完全不一样。看起来像是语言本身的关键字一样。

比如,移位并不是运算符,也不是关键字,而是一个被infix修饰的二元参数函数:

finfix un Int.shr(x: Int): Int {...}

8.shr(2) // 这样正常调用也完全可以,把整数8右移2位
8 shr 2 // 这是infix式的用法,其实是等同于上面的函数调用

infix必须是Extension function,并且只能有一个参数,算上Extension function的接收对象,其实一共是2个参数。标准库中也定义了大量的infix,如整数位移的shr和shl。以及像一些DSL中的函数,都会定义成infix,以让代码更简洁。

总之,下次再见到 a xyz b这种写法时,不用害怕,并不是有了新的关键字,这里的xyz是infix notation,把它当成函数调用 xyz(a, b)就好了。

参考资料

  • Kotlin Infix Function Call
  • Infix Functions in Kotlin

inline Functions

常规的lambda会有closure(捕获上下文中的对象),在编译后会产生很多对象,这会导致一些性能问题,但这是标准的函数式编程。

但某些情况下,我提供的是一个单纯的行为(lambda),比如像Collections的forEach以及filter,传入的lambda也好,或者其他函数也好,这是一个单纯的行为,你在集合中遍历时执行它就好。这种情况好,我们希望高阶函数在其函数体内直接使用传入的函数参数就可以了,不需要进行常规的对象创建(closure对象以及函数接口对象)。就可以使用inline关键字来修饰这人高阶函数。

参考资料

  • Inline Functions in Kotlin
  • inline function in Kotlin
  • Kotlin Inline Functions

欢迎搜索并关注 公众号「稀有猿诉」 获取更多的优质文章!

原创不易,「打赏」「点赞」「在看」「收藏」「分享」 总要有一个吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/479945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第6讲-MIPS处理器(3)MIPS单周期处理器设计

三. MIPS单周期处理器设计 1.单周期数据通路设计 2.单周期控制器设计 3.单周期性能分析

阿里云服务器ECS经济型e实例2核2G优惠价格99元一年性能测试

阿里云服务器99元一年配置为云服务器ECS经济型e实例&#xff0c;2核2G配置、3M固定带宽和40G ESSD Entry系统盘&#xff0c;新用户和老用户均可买&#xff0c;续费不涨价依旧是99元一年&#xff0c;阿里云服务器网aliyunfuwuqi.com来详细说下阿里云99元服务器性能测评&#xff…

碳素光线疗法——动,植物 光育实验

碳素光线疗法——动&#xff0c;植物 光育实验 碳素光线疗法&#xff1a; 中西医、民间疗法融为一体&#xff0c;提高机体自身治愈力&#xff0c;免疫力&#xff0c;改善体质和保持健康&#xff0c;有助于疾病的预防和治疗的疗法。不吃药、不打针、不手术也能得健康&#xff0c…

HCIP的学习(3)

网络类型及数据链路层协议 网络类型分类 P2P网络----点到点网络类型MA网络-----多点接入网络 BMA----广播型多点接入网络NBMA—非广播型多点接入网络&#xff08;快淘汰了&#xff09; 数据链路层协议 MA网络 以太网协议 特点&#xff1a;需要使用MAC地址对设备进行区分…

经济事件对我们投资没影响吗?昂首资本的这两个实例说明白再说

各位投资者现在还不明白经济事件对我们投资的影响吗&#xff1f;下面昂首资本就通过两个实例&#xff0c;各位投资者能否明白经济事件对我们投资的影响。 2015年6月4日&#xff0c;澳大利亚零售量新闻发布。分析师预计销量增幅高达0.4%&#xff0c;但是结果却大吃一惊&#xf…

第四百一十七回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"自定义标题栏"相关的内容&#xff0c;本章回中将介绍自定义Action菜单.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在这里提到的…

【代码学习】Mediapipe人脸检测使用记录

Mediapipe&#xff0c;每秒200-300帧的实时人脸检测&#xff0c;提取画面中的人脸框&#xff0c;实现后续各种应用&#xff1a;人脸属性识别、表情识别、关键点检测、三维重建、增强现实、AI换妆等 code&#xff1a;google/mediapipe: Cross-platform, customizable ML soluti…

【NLP】从变形金刚到Transfomer 01

Transformer是一种非常强大的模型&#xff0c;在自然语言处理&#xff08;NLP&#xff09;领域里引起了一场革命。 "从变形金刚到技术革命家&#xff0c;Transformer不再仅是儿时屏幕上的英雄。&#x1f916;✨ 在今天的AI领域&#xff0c;它变身成为自然语言处理的超级英…

MySQL数据库存储引擎MyISAM与InnoDB

前言 MySQL存储引擎是MySQL数据库中负责管理数据存储和检索的组件&#xff0c;不同的存储引擎提供了不同的功能和特性&#xff0c;可以根据实际需求选择合适的存储引擎来优化数据库性能和功能。以下是一些常见的MySQL存储引擎&#xff1a;InnoDB、MyISAM、MEMORY、NDB Cluster…

论文阅读-MIPD:一种用于分布式深度神经网络训练的自适应梯度稀疏化框架

摘要—基于参数服务器架构的异步训练广泛应用于大规模数据集和深度神经网络模型的扩展训练。在大规模分布式深度学习系统中&#xff0c;通信一直被认为是主要瓶颈。最近的研究尝试通过梯度稀疏化和量化方法来减少通信流量。我们发现前期研究存在三个限制。首先&#xff0c;他们…

【基础+进阶】Midjourney订阅看这一篇就够了!Midjourney进阶关键词用法!Midjourney常见问题!

Midjourney进阶关键词用法 1.风格 设计/流派 可以使用一些关键词作为设计流派风格&#xff0c;例如standard,Japanese anime style,Pixar movie style,cyber punk style等 艺术家的姓名 可以使用一些艺术家的姓名作为风格&#xff0c;例如Andy Warhol,Da Vinci等 渲染/照明…

​浅析多模态大模型技术路线梳理

前段时间 ChatGPT 进行了一轮重大更新&#xff1a;多模态上线&#xff0c;能说话&#xff0c;会看图&#xff01;微软发了一篇长达 166 页的 GPT-4V 测评论文&#xff0c;一时间又带起了一阵多模态的热议&#xff0c;随后像是 LLaVA-1.5、CogVLM、MiniGPT-5 等研究工作紧随其后…

【系统架构师】-第6章-数据库设计基础知识

1、三级模式-两级映像 外模式&#xff1a;视图、用户与数据库的接口 概念模式&#xff1a;表 内模式&#xff1a;存储方式&#xff0c;索引创建等 1&#xff09;外模式-模式映射&#xff1a; 视图与表的映射&#xff0c;表数据发生修改&#xff0c;只需要修改映射&#xf…

探索ChatGPT时代下的下一代信息检索系统:机遇与挑战

1 Introduction 2022 年 11 月 30 日&#xff0c;OpenAI 推出了 ChatGPT&#xff0c;这是一款由先进的 GPT3.5 和更高版本的 GPT-4 生成语言模型提供支持的 AI 聊天机器人应用程序。该应用迅速吸引了全球超亿用户&#xff0c;创下了产品快速传播的新纪录。 它能够以对话的方式…

【Linux系统编程】文件系统

进程与文件 当我们对文件进行操作时&#xff0c;文件必须要被加载到内存中&#xff0c;然后CUP从内存中拿到此文件进行操作&#xff0c;没有打开的文件放在磁盘中存储。 文件的打开其实也是设计到内部某个进程。无论是系统调用&#xff0c;还是专有库中的函数&#xff0c;都是…

软考 网络工程师 每日学习打卡 2024/3/22

学习内容 第9章 网络操作系统与应用服务器 本章主要讲解&#xff1a;了Windows和Linux操作系统的基础知识&#xff0c;并详细讲述了常用的各种服务器的 配置方法。这一章的内容主要是在具体操作方面&#xff0c;网络工程师要能够熟练地配置各种网络服务 器&#xff0c;排除网络…

Linux内核编译与安装

Linux内核介绍 Linux内核是一个用C语言写成的&#xff0c;符合POSIX标准的类Unix操作系统。内核是操作系统中最基本的一部分&#xff0c;提供了众多应用程序访问计算机硬件的机制。Linux内核的一大特点就是采用了整体式结构&#xff0c;有很多过程组成&#xff0c;每个过程都可…

hadoop namenode 查看日志里面报错8485无法连接

一、通过日志排查问题&#xff1a; 1、首先我通过jpsall命令查看我的进程&#xff0c;发现namenode都没有开启 2、找到问题后首先进入我的日志目录里查看namenode.log [rootnode01 ~]# /opt/yjx/hadoop-3.3.4/logs/ [rootnode01 ~]# ll [rootnode01 ~]# cat hadoop-root-nam…

手拉手Java爬虫HttpClient

JAVA爬虫 HttpClient HttpClient 是Apache Jakarta Common 下的子项目&#xff0c;可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新的版本和建议。 使用 HttpClient 的 6 个步骤 1. 创建 HttpClient 的实例 2…

环信新版单群聊UIKit集成指南——Android篇

前言 环信新版UIKit已重磅发布&#xff01;目前包含单群聊UIKit、聊天室ChatroomUIKit&#xff0c;本文详细讲解Android端单群聊UIKit的集成教程。 环信单群聊 UIKit 是基于环信即时通讯云 IM SDK 开发的一款即时通讯 UI 组件库&#xff0c;提供各种组件实现会话列表、聊天界…