IT评测·应用市场-qidao123.com技术社区
标题:
【解密 Kotlin 扩展函数】顶级函数和顶级属性(十五)
[打印本页]
作者:
美丽的神话
时间:
2024-9-23 18:38
标题:
【解密 Kotlin 扩展函数】顶级函数和顶级属性(十五)
1.1.1 摆脱静态实用类的束缚–顶级函数
我们都知道,作为一种面向对象的语言,Java要求
将所有代码都写成类的方法
通常情况下,这样做效果很好,但在实际中,几乎每个大型项目
最终都会
产生大量不属于任何一个类的代码
偶尔,
一个操作会与两个不同类的对象
一起工作
而
这两个类对该操作起着同等紧张的作用
另有一些时候,虽然
只有一个主对象
不想通过将操作添加为实例方法
来臃肿其 API
因此,你最终会
得到不包含任何状态或实例方法的类
—实用工具类
这种类
只充当几个静态方法的容器
JDK 中的 Collections 类就是一个很好的例子
要在开源项目中找到其他例子,请查找
名称中包含 Util 的类
在 Kotlin 中,
不必要创建那些毫无意义的类
相反,可以
直接将函数放在源文件的顶层
,
任何类的外边
这些函数
仍然是文件顶层声明的包的成员
如果想
从其他包中调用这些函数
,仍然
必要导入它们
但
不必要的额外嵌套层
已
不复存在
创建一个名为 Join.kt 的文件,
直接将 joinToString 函数放到 strings 包
中
关于joinToString 函数的实现–传送门
package strings
@JvmOverloads
fun <T> joinToString(
collection: Collection<T>,
separator: String = ", ",
prefix: String = "",
postfix: String = ""
) : String {
val result = StringBuilder(prefix)
for ((index, elem) in collection.withIndex()){
if (index > 0) result.append(separator)
result.append(elem)
}
result.append(postfix)
return result.toString()
}
复制代码
如今,让我们看看
编译成相同类的 Java 代码
<1> 可以看到,
Kotlin 编译器生成的类名
与
包含函数的文件名同等
大写以匹配 Java 的定名规范
,
后缀为 Kt
<2>
文件中的所有顶级函数
都
被编译为该类的静态方法
<3> 因此,
从 Java 中调用该函数
就
像调用其他静态方法一样简单
/* Java */
package strings;
public class JoinKt { // <1>
public static String joinToString(// ... ) { // ... } // <2>
}
===========================================================
/* Java */
import strings.JoinKt;
// ...
JoinKt.joinToString(list, ", ", "", ""); // <3>
复制代码
1.1.2 更改顶级声明所在的类名
默认情况
下,
编译器生成的类名与文件名相对应
,并
带有 Kt 后缀
要
更改包含 Kotlin 顶级函数的生成类名称
可以
添加一个 JvmName 注解
<1>
将其放在文件开头
,
包名之前
<2> 此时
在Java代码中导入
时, 可以
直接利用新定名"StringFunctions"
@file:JvmName("StringFunctions") // <1>package strings
@JvmOverloads
fun <T> joinToString(
collection: Collection<T>,
separator: String = ", ",
prefix: String = "",
postfix: String = ""
) : String {
val result = StringBuilder(prefix)
for ((index, elem) in collection.withIndex()){
if (index > 0) result.append(separator)
result.append(elem)
}
result.append(postfix)
return result.toString()
}
======================================================import java.util.List;import strings.StringFunctions; // <2>public class Example { public static void main(String[] args){ System.out.println(StringFunctions.joinToString(List.of("1", "2"))); }}
复制代码
1.1.3 顶层属性
与函数一样,
属性也可以放在文件的顶层
在类外部存储单个数据并不常见
,但
仍然很有用
例如,你可以利用 var 属性来
计算某些操作的实行次数
<1> 声明顶级属性
<2> 改变属性的值
<3> 读取属性的值
var opCount = 0 // <1>
fun performOperation() {
opCount++ // <2>
// ...
}
fun reportOperationCount() {
println("Operation performed $opCount times") // <3>
}
复制代码
顶级属性还
答应在代码中定义常量
: val UNIX_LINE_SEPARATOR = “\n”
默认情况
下,
顶层属性与其他属性一样
以访问器方法的形式暴露给 Java 代码
的
val 属性的 getter 和 var 属性的 getter-setter 对
<1> 如果想
将常量作为"public static final"字段
暴露给 Java 代码
使其利用更自然,可以
利用 const 修饰符对其进行标志
这
对基本类型和String类型
的属性都是答应的
<2> 与顶级函数一样,顶级属性在编译后会酿成Java的静态字段
由于这里
利用const修饰属性
,所以会
得到"public static final"字段
*
const val UNIX_LINE_SEPARATOR = "\n" // <1>
=============================================== // <2>
/* Java */
public static final String UNIX_LINE_SEPARATOR = "\n";
复制代码
注意 Kotlin 标准库还
包含几个有用的顶级函数和属性
kotlin.math 包就是一个例子
它
为典型的数学运算和三角运算
提供有用的函数
<1> 例如用于
计算两个数字最大值的 max 函数
它还
提供许多数学常量
,如
欧拉数或圆周率
fun main() {
println(max(PI, E)) // <1>
// 3.141592653589793
}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/)
Powered by Discuz! X3.4