Kotlin学习记录(一)

1.when语句

如果when语句的每个分支都会返回值,如下:

1
2
3
4
5
6
7
8
fun fact(n:Int):Int {
var result
when (n) {
0, 1 -> result = 1
else -> result = n * fact(n - 1)
}
return result
}

那可以写成这种形式

1
2
3
4
5
6
fun fact(n:Int):Long {
return when (n) {
0, 1 -> 1
else -> n * fact(n - 1)
}
}

在 Kotlin里,if,when,try都可以是一个表达式,返回一个值;表达式可以是一个语句块,返回值是最后一个语句的值。


2. Kotlin中return语句会从最近的函数或匿名函数中返回,但是在Lambda表达式中遇到return语句直接返回最近的外层函数,比较下面两个代码片段

1
2
3
4
5
val intArray = intArrayOf(1, 2, 3, 4, 5)
intArray.forEach {
if (it == 3) return
println(it)
}

输出:1 2

1
2
3
4
5
6
7
val intArray = intArrayOf(1, 2, 3, 4, 5)
intArray.forEach (
fun (a:Int) {
if (a == 3) return
println(a)
}
)

输出:1 2 4 5


3. object对象和伴生对象
Kotlin中没有静态属性和方法,可以使用object声明一个object单例对象

1
2
3
4
5
6
object User {
val username: String = "brick"
fun say() {
println("Hello!")
}
}

伴生对象,顾名思义就是和一个类相伴而生的对象,它和包含它的外部类是一一对应的,通过外部类的类名来访问它的属性方法,类似于Java里访问类的静态属性和方法:
一般使用方法:

1
2
3
4
5
6
7
8
9
class NumberTest {
companion object Obj{
val flag = false

fun plus(num1: Int, num2: Int): Int {
return num1 + num2
}
}
}

这里为NumberTest类定义了伴生对象Obj,Obj这个名字可有可无,Kotlin本身访问伴生对象时不关心这个名字:

1
println("Hello World!!"+ NumberTest.plus(1,2))

不过Java代理访问时需要用到这个名字,如果没有要用Companion代替:

1
2
System.out.println("HelloWorld: "+NumberTest.Obj.getFlag());
System.out.println("HelloWorld: "+NumberTest.Companion.getFlag());

如果想让Java访问形式和Kotlin的完全一致,可以用到const关键字或者@JvmField、@JvmStatic注解来修饰属性方法,如下:

1
2
3
4
5
6
7
8
9
10
11
12
class NumberTest {
companion object Obj{
const val flag = false

@JvmField
var name = "brick"
@JvmStatic
fun plus(num1: Int, num2: Int): Int {
return num1 + num2
}
}
}

1
2
System.out.println("HelloWorld: "+NumberTest.flag);
System.out.println("HelloWorld: "+NumberTest.plus(1, 2));

4.函数式编程的焦点是数据的映射;命令式编程的焦点是解决问题的步骤。

函数式编程是转换数据而非修改原始数据