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