首先你要有个女朋友
其次要回答 3 个灵魂拷问
- 使用成本
- 能节省什么
- 能带来什么
最好是感知不到是在写代码。
实操
上篇《距离全栈 你只差一个 kotlinx》聊到了
Kotlin
借助 Lambda
+ Extensions扩展
来实现内部 DSL,这次展开聊聊 扩展
和 操作符重载
是如何让你的代码不像代码的。
扩展
Kotlin 可以对一个类的属性和方法进行扩展,且不需要继承或使用 Decorator 模式。
扩展是一种静态行为,对被扩展的类代码本身不会造成任何影响。
扩展方法
如果我希望对一个已有类增加一个方法,就可以直接给这个类增加扩展方法,同时所有的对象都可以调用这个扩展方法。
举例说明
扩展属性
扩展属性与成员变量不同,因为扩展不会真的在类中插入一个成员变量。因此扩展属性不能初始化,只能通过 getter 方法定义
操作符重载
Kotlin 允许我们为自己的类型提供预定义的一组操作符实现(这些操作符都对应的成员函数或扩展函数),他们是一一对应的
算术运算符 operator
基本类型中,Int + Int
表示数字相加, String + String
则代表了字符串拼接,那么如果是 ArrayList<String> + String
呢?
kotlin 中重载了 Collection 的算术运算符,其中 plus
对应了 +
的操作函数。所以 ArrayList<String> + String
会把 String
添加到 ArrayList<String>
集合中
我们也可以自定义 +
的重载,比如将 String
拼接到 ArrayList<String>
每个元素的末尾
看起来和扩展函数有些类似,我们继续放飞
中缀表示法 infix
标有 infix 关键字的函数也可以使用中缀表示法(忽略该调用的点与圆括号)调用。中缀函数必须满足以下要求:
- 它们必须是成员函数或扩展函数;
- 它们必须只有一个参数;
- 其参数不得接受可变数量的参数且不能有默认值。
通过这种表示方法,我们的代码逻辑可以变成陈述句
并且有 IDE 的高亮及语法提示支持
这条用例的代码元素还有 2 个,JUnit
+ fun
调用操作符 invoke
调用操作符
圆括号转换为调用带有适当数量参数的 invoke。
表达式 | 翻译为 |
---|---|
a() | a.invoke() |
a(i) | a.invoke(i) |
a(i, j) | a.invoke(i, j) |
a(i_1, ……, i_n) | a.invoke(i_1, ……, i_n) |
我们可以通过重载 invoke
的方法移除 fun
的概念,变成 标题 {内容}
的格式进行触发函数。 而 JUnit
可以通过父类完成 TestCase 的注册
kotest
Kotest is a flexible and comprehensive testing project for Kotlin with multiplatform support.
TestCase 的注册,以及如何在 idea 中运行某个测试方法比较复杂,我们可以直接使用 Kotest
及其插件完成。而 Kotest
的实现原理就是上文提到的扩展以及操作符重载
解答
看一下是否能回答上述灵魂拷问
1. 使用成本
- 通过 IDE 约束及提示,简化编写成本
- 增加了额外的约束。但是从 DDD 的过程来看,统一语言在团队协作方面有着重要地位。命名表明了你对事物的理解,所以团队内统一描述语言是很有必要的
2. 能节省什么
- 通过代码和工具函数的封装,可以简化重复操
- 可以直接调用开发代码方法及接口
- 通过封装简化接口自动化成本
如果看不懂这个语法,可以看上一篇的 DSL
3. 能带来什么
- 配合 CICD 在潜移默化中完成自动化测试并输出测试报告
- 借助代码管理工具(gitlab、github),完成统计、review、操作留痕、版本等管理操作
结论
- 为什么标题说 java,内容都是 kotlin? 因为这篇是标题党
- 使用扩展 or 重载时,一定要明确函数作用域
- 为什么要做扩展和操作符重载?Because I can
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于