函数
从最经典的例子开始:一个打印“Hello,world!”的程序。
fun main(args: Array<String>) {
println("Hello,World!");
}
现在来分析下这段代码:
- 使用关键字fun来声明一个函数
-
args
是参数名字 - 参数的类型写在参数名的后面,即
Array<String>
- 函数返回值类型定义位置紧跟小括号后面,如
fun test(): Int {}
,若没有返回值可以不写 - 函数可以定义在文件最外层,就是说可以定义在类之外,java的函数需要定义在类的里面,像js就可以定义在文件的最外层
- 数组就是类,和Java不同,kotlin没有声明数组类型的特殊语法
- 使用println代替了System.out.println
- 可以省略每行代码结尾的分号,与js一样
- 文件若放在默认包里面,第一行不会使用关键字package标识,若在自定义的包里,包名会声明在源文件的顶部,倘若需要使用到其他包的函数或类等,可以使用import关键字,这些语法与Java一样
变量
声明变量的关键字有两个:
-
val
,不可变引用。使用val声明的变量不能在初始化之后再次赋值。它对应Java的final
变量 -
var
,可变引用。这种变量的值可以被改变。这种声明对应的是普通(非final
)的Java变量
val a: Int = 1 // 立即赋值
val b = 2 // 类型推断,和js一样
val c: Int // 若只是声明而没有赋值,初始化类型不能省略
var x = 5 // 自动推断出 `Int` 类型
x += 1
// 顶级变量,可以理解为全局变量,在js中也比较常见
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
字符串模板
// 常见的
val i = 10;
println("i=$i")
// 用花括号括起来的任意表达式
val s = "abc"
println("$s.length is ${s.length}")
// 在原始字符串中表示字面值`$`字符,它不支持反斜杠转义
val price = """
${'$'}9.99
"""
类型
在kotlin中,所有东西都是对象,在这个意义上讲可以在任何变量上调用成员函数与属性。其基本类型主要有数字、字符、布尔值、数组与字符串。
数字
- Double-64bit
- Float-32bit
- Long-64bit
- Int-32bit
- Short-16bit
- Byte-8bit
注意:
- 在kotlin中字符不是数字
- Long类型使用大写L标记
- 浮点数默认是Double型,Float使用f或F标记
- 可以使用“_”增强可读性,如
val oneMillion = 1_000_000
- 较小的类型不能隐式转换为较大的类型
字符
- 使用
Char
类型表示 - 不能直接当作数字
- 用单引号
''
括起来 - 特殊字符使用反斜杠转义
布尔
用Boolean
表示,有两个值:true
和false
。
数组
使用Array
类来表示,其内部已经定义了get
和set
函数以及属性size
。
// 初始化一个数组
var arr1 = arrayOf(1, 2, 3)
println(arr1.get(0)) // 1
println(arr1[0]) // 1
// 初始化一个长度为10的Int类型的数组
var arr2 = arrayOfNulls<Int>(10)
// 初始化一个长度为5的数组,lambda的含义:asc[i] = (i * i).toString() ,i是索引
var asc = Array(5, { i -> (i * i).toString() })
asc.forEach { println(it) } // 0 1 4 9 16
字符串
字符串用String
类型表示。
- 字符串是不可变的
- 可以使用
[]
来访问,如s[i]
- 可以使用
for
循环迭代 - 可以使用
+
操作符连接字符串 - 原始字符串,使用三个引号
""" """
将内容括起来,内部没有转义并且可以包含换行以及任何其他字符
if表达式
在kotlin中,if
是表达式,而不是语句,它有返回值,而java中的if
是语句。
// 作为表达式
// 若if作为表达式而不是语句,该表达式需要有else分支
val max = if (a > b) a else b
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
when表达式
when
取代了类C语言的switch操作符,与if
相似。
// 简单形式
when (x) {
1 -> print("x=1")
2 -> {
print("x=2")
}
else -> print("x既不是1也不是2")
}
// 可以合并分支
when (x) {
1, 2 -> print("x=1 or x=2")
else -> print("x既不是1也不是2")
}
// 可以使用任意表达式作为分支条件
when (x) {
x == 1 -> print("x=1")
x == 2 -> print("x=2")
else -> print("x既不是1也不是2")
}
when (x) {
in 1..10 -> print("x在这个区间")
!in 10..20 -> print("x不在这个区间")
else -> print("x都不在这些区间")
}
// 检测这个值是或者不是一个特定的类型的值
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
// 不带参数,和if-else if链一样的功能
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
while循环
kotlin中的while
循环和do-while
循环和Java中相应的循环没有什么区别。
for循环
for
循环会配合in
运算符来一起使用,很灵活。
// 在数字区间上迭代
for (i in 1..3) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
// 通过索引遍历一个数组或者一个list
for (i in array.indices) {
println(array[i])
}
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
区间
使用..
运算符来表示,如1..10
,但它是闭区间的,常常结合in
或!in
运算符来检查一个值是否在区间中,可以达到迭代数据的目的。
// 顺序遍历
for (i in 1..4) print(i)
// 逆序遍历
for (i in 4 downTo 1) print(i)
// 以不等于1的任意步长迭代数字
for (i in 1..4 step 2) print(i)
for (i in 4 downTo 1 step 2) print(i)
// 不包含结束元素
for (i in 1 until 10) {
// i in [1, 10) 排除了 10
println(i)
}
异常
kotlin的异常处理和Java以及其他许多语言处理方式相似。一个函数可以正常结束,也可以在出现错误的情况下抛出异常。方法的调用者能捕获到这个异常并处理它;如果没有被处理,异常会沿着调用栈再次抛出。
kotlin的异常更多的时候是作为表达式来使用。另外,kotlin没有受检异常。
// 传统用法
throw Exception("Hi There!")
try {
// 一些代码
} catch (e: SomeException) {
// 处理程序
} finally {
// 可选的 finally 块
}
// throw表达式
val number = 20
val per =
if (number in 0..100)
number
else
throw IllegalArgumentException(
"A per value must be between 0 and 100:$number"
)
// try作为表达式
val a: Int? = try {
parseInt(input)
} catch (e: NumberFormatException) {
null
}
可空性
当某个变量的值可以为null
的时候,必须在声明处的类型后添加?
来标识该引用可为空。
fun parseInt(str: String): Int? {
}
fun myPrintln(str: String?) {
}
网友评论