函数的定义与调用
一、预备知识:在Kotlin中创建集合
fun main(args: Array<String>) {
//Kotlin中定义各自集合
val set= hashSetOf<Int>(,,,)
val list= arrayListOf<Int>(,,)
val map= hashMapOf<Int,String>( to "one", to "tow") //为了更容易与Java代码交互,Kotlin采用的是标准的Java集合类
println(set.javaClass)
println(list.javaClass)
println(map.javaClass) /*class java.util.HashSet
class java.util.ArrayList
class java.util.HashMap*/ //与Java不同,可以这样用
println(set.max())
println(list.last())
}
二、让函数更好地调用
一)命名参数和默认参数值
class Doa{
fun <T> joinToString(
collection: Collection<T>,
//参数默认值
separator: String="|",
prefix: String="{",
postfix: String="}"
): String{
val result=StringBuilder(prefix) for ((index,element) in collection.withIndex()){
if (index>) result.append(separator)
result.append(element)
} result.append(postfix)
return result.toString()
}
} fun main(args: Array<String>) { val doa = Doa()
val list= listOf<Int>(,,,,,)
//函数调用时可以指明参数名,被省略的采用默认值
val str = doa.joinToString(collection = list,separator = "\\")
println(str)
}
二)消除静态类工具:顶层函数和属性
//该注解重命名自动生成的类名
@file:JvmName("ALei")
package gemetry //顶层属性
var count= //编译器会自动生成与文件名同名的类,顶层函数是类中的静态方法
fun <T> joinToString(
collection: Collection<T>,
//参数默认值
separator: String="|",
prefix: String="{",
postfix: String="}"
): String{
count++
val result=StringBuilder(prefix) for ((index,element) in collection.withIndex()){
if (index>) result.append(separator)
result.append(element)
} result.append(postfix)
return result.toString()
} fun main(args: Array<String>) {
var list= listOf<Int>(,,)
println(joinToString(list))
println("The function is executed $count times")
}
三、给别人的类添加方法:扩展函数和属性
package gemetry //只要一个类能被JVM编译成类,就可以定义扩展函数
//在扩展函数中可以直接访问扩展的类其他方法和属性
//但是并不允许打破其封装性,不能访问私用的和受保护的成员
fun String.lastChar(): Char=get(length-)
//fun String.lastChar() : Char=this.get(this.length-1) fun main(args: Array<String>) {
println("Kotlin".lastChar())
}
在Java中使用扩展函数:
package gemetry; public class UseExtension { public static void main(String[] args){
//实质上扩展函数就是一个静态函数
char c=ExtensionMethodKt.lastChar("Java");
System.out.println(c);
}
}
注意:既然扩展函数实质是一个静态函数,当然不能被子类重写
2.如果一个类的成员函数和扩展函数有相同的签名,成员函数会被优先使用
当然可以这么玩儿:
fun Collection<String>.join(
separator: String=",",
prefix: String="(",
postfix: String=")"
)=joinToString (separator,prefix,postfix)
关于扩展属性,你可以把它当作扩展函数的值。
四、处理集合:可变参数、中缀调用和库的支持
一)可变参数
//可变参数声明
fun test(vararg values: String){
for (value in values){
println(value)
}
} fun main(args: Array<String>) {
test("tang","jiu","jia")
//与Java中不同,可以这样使用可变参数,此功能被称为展开运算符
var list= arrayOf("TANG","JIA","PI")
test(*list)
}
二)键值对处理:中缀调用和解构声明
//下面的代码"to"不是内置结构,而是一种特殊的函数调用,被称为中缀调用
val map= mapOf<Int,String>( to "one", to "tow")
//区别一般函数调用
//1.to("one") /**
* 中缀调用可以与只有一个参数的函数一起使用,无论是普通函数还是扩展函数
* 要允许使用中缀符号调用函数,需要使用infix修饰符来标记它。
*/
infix fun String.too(other: String)=Pair(this,other) fun main(args: Array<String>) {
//可以这样初始化"一对"变量
val (number,name)= "one" too "Shadowplay"
println("$number: $name")
}
五、字符串和正则表达式的处理
String str="78.11-7.B";
//Java中Split方法的缺陷:不适用于".",这里返回的list为一个空数组
//因为他将一个正则表达式作为参数,并根据表达式将字符串成多个字符串
String[] list = str.split(".");
for (String value:list){
System.out.println(value);
}
fun main(args: Array<String>) {
//Kotlin把这个令人费解的函数隐藏了,并提供了一个可正常使用的重载函数。
val javaSplit: String="78.11-7.B"
val list = javaSplit.split(".")
for (str in list) println(str)
//可指定多个分隔符
println(javaSplit.split(".","-"))
}
/**
* 使用扩展函数来解析字符串
* */
fun parsePath(path: String){
val dir=path.substringBeforeLast("/")
val fullName=path.substringAfterLast("/")
val fileName=fullName.substringBeforeLast(".")
val extension=fullName.substringAfterLast(".") println("Dir: $dir, name: $fileName, extension: $extension")
}
六、让你的代码更整洁:局部函数及扩展
fun saveUser(user: User){
//局部函数可以访问所在函数中的所有参数和变量
fun validate(value: String,fileName: String){
if (value.isEmpty()){
throw IllegalArgumentException("Can't save user ${user.id} empty $fileName")
}
}
validate(user.name,"Name")
validate(user.address,"Address")
}