Kotlin 定义函数的一些语法
fun main(args:Array<String>):Unit { val x:() -> Unit = { println("hello") } // 无参数函数,声明类型时用 ()-> 实现时不能要,{() -> println("hello")} 是错误的 val odd:(Int) -> Boolean = { x -> x % 2 ==1 } // 类型声明参数要放到括号中(即使只有一个参数 val add:(Int,Int) -> Int = { x,y -> x+y } //函数实现不能用括号即使有多个参数 val sum = { x:Array<Int> -> var s = 0;for(i in x) s+=i;s } } fun main(args:Array<String>){ val is_odd:(Int)->Boolean = { x -> x % 2 == 1 }//类型声明中参数类型列表的括号不能省略 val is_even = { x:Int -> x % 2 == 0 } val add:(Int,Int)->Int = { x , y -> x +y } fun mul(x:Int,y:Int):Int = x * y // 这种定义的效率最高,其他的定义被编译成 extends Lambda implements Function2 val sub = fun(x:Int,y:Int) = x - y; println(is_odd(2)); println(is_even(2)); println(add(2,3)); println(mul(2,3)); println(sub(2,3)); }
operator fun invoke
fun main(args:Array<String>):Unit { val x = A(3)//有参数构造函数不会与伴生对象定义的invoke()歧义,但是可能会和 invoke(x)歧义。 x();//调用实例对象定义在类中的invoke方法 A();//如果A有无参构造函数就会与 object invoke 的括号调用歧义,将无法直接用括号调用返回 world 的函数 B();//没有伴生类的对象定义invoke方法不会产生直接括号调用与无参构造函数的歧义 A("wengmj");//如果么有定义A.invoke(String)则定义的A.invoke函数有效 } class A(val x:Int) { init{ println("hello") } operator fun invoke():Unit{ println("abc") } companion object{ operator fun invoke():Unit{ println("world") } operator fun invoke(x:String):Unit{ println(x) } } } object B { operator fun invoke():Unit{ println("def") } }
实现一个可迭代的类
//传统的实现迭代接口方法 class A : Iterator<Int> { val x = arrayOf(1,2,3,4,5).iterator(); override fun next(): Int = this.x.next(); override fun hasNext(): Boolean = this.x.hasNext(); } // 实现 operator fun iterator() class A { val x = arrayOf(1,2,3,4,5).iterator(); operator fun iterator():Iterator<Int> = this.x.iterator(); } //扩展一个已有的类使其可迭代 class A() { val x = arrayOf(1,2,3,4,5).iterator(); } operator fun A.iterator():Iterator<Int> = this.x.iterator(); fun main(args:Array<String>):Unit { for(x in A()) println(x) }
类扩展函数和属性
val String.hasChar:(Char) -> Boolean get()= {c:Char -> this.any{ it == c}}
val String.leng:Int //类的属性扩展不能放在函数里:Local extension properties are not allowed get() = this.length; fun main(args:Array<String>):Unit { fun String.len():Int{ //函数里定义扩展函数是可以的 return this.length; } println("hello".hasChar('e')) println("hello".len()) println("hello".leng) }
构造一个递归结构的列表
//扩展实现 IntRange to Array fun IntProgression.toArray() = Array<Int>(( last - first) / step + 1 , { this.elementAt(it) }) fun main(args:Array<String>):Unit { val p = (1..100 step 10).toArray(); val list = L<Int>(*p).push(1000) // 数组作为 vararg 参数,变量前加 * print(sum(list)) } //递归列表 class L<T> private constructor(val h:T,val t:L<T>?){ fun push(h:T):L<T> = L<T>(h,this); companion object { operator fun <T> invoke(vararg args:T):L<T> { var x = L(args[0],null); for(i in 1..args.lastIndex) x = L(args[i],x); return x; } } } //用于校验的递归求和函数 fun sum(list:L<Int>):Int { with(list) { if(t == null) return h; return h + sum(t) } }
泛型Demo
class A<T>(val name:T){ companion object{ fun <T> say(x:T){ println(x); } } fun hello(){ println("hello ${this.name}"); } } fun main(args:Array<String>):Unit { A.say<String>("hello"); A<Int>(123).hello(); }
匿名函数和λ表达式
fun main(args:Array<String>):Unit { val ins = arrayOf(-1,-2,1,2,3,4); /* 如果一个函数用另一个函数作为它的最后一个参数, λ 表达式可以放在小括号外面的大括号中, 如果最后一个函数参数同时是唯一的参数则小括号也可以省略. */ val x = ins.filter { x -> x > 0 } println(x) //如果用匿名函数则只能放在小括号中 val y = ins.filter (fun(x:Int):Boolean { return x>0 }); println(y) }