函數的定義與調用
一、預備知識:在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 }