kotlin学习一:基础
基本类型
整数四种类型:
浮点数类型:默认 double:123.5、123.5e10,Float 用 f 或者 F 标记: 123.5f
类型 | 大小(比特数) | 有效数字比特数 | 指数比特数 | 十进制位数 |
---|---|---|---|---|
Float | 32 | 24 | 8 | 6-7 |
Double | 64 | 53 | 11 | 15-16 |
Byte | 8 | -128-127 | ||
Short | 16 | -32768-32767 | ||
Int | 32 | -2,147,483,648 (-231) | ||
Long | 64 | -9,223,372,036,854,775,808 (-263) |
大数可以采用面值下划线:增强可读性
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
类型转换
因此较小的类型不能隐式转换为较大的类型
可以显式转换来拓宽数字
val i: Int = b.toInt() // OK:显式拓宽
print(i)
算数运算会有重载,会适当的转换;
val l = 1L + 3 // Long + Int => Long
位运算
val x = (1 shl 2) and 0x000FF000
这是完整的位运算列表(只用于 Int
与 Long
):
shl(bits)
– 有符号左移shr(bits)
– 有符号右移ushr(bits)
– 无符号右移and(bits)
– 位与or(bits)
– 位或xor(bits)
– 位异或inv()
– 位非
布尔运算true 与 false。
||
– 短路逻辑或&&
– 短路逻辑与!
- 逻辑非
变量赋值
val
只能复制一次:写法:
val a: Int = 1 // 立即赋值
val b = 2 // 自动推断出 `Int` 类型
val c: Int // 如果没有初始值类型不能省略
c = 3 // 明确赋值
var
可重新赋值的变量,
var x = 5 // 自动推断出 `Int` 类型
x += 1
举例:
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
空值与null:
可以为null时,需要在类型后面加?
当某个变量的值可以为 null 的时候,必须在声明处的类型后添加 ? 来标识该引用可为空。
如果 str 的内容不是数字返回 null。
//类型后面加?表示可为空
var age: String? = "23"
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1
当一个引用可能为 null 值时, 对应的类型声明必须明确地标记为可为 null。
当 str 中的字符串内容不是一个整数时, 返回 null:
fun parseInt(str: String): Int? {
// ...
}
以下实例演示如何使用一个返回值可为 null 的函数:
fun main(args: Array<String>) {
if (args.size < 2) {
print("Two integers expected")
return
}
val x = parseInt(args[0])
val y = parseInt(args[1])
// 直接使用 `x * y` 会导致错误, 因为它们可能为 null.
if (x != null && y != null) {
// 在进行过 null 值检查之后, x 和 y 的类型会被自动转换为非 null 变量
print(x * y)
}
}
字符串使用
$,来提取变量为字符串,或者${ },来使用字符串。
var a = 1
// 模板中的简单名称:
val s1 = "a is $a"
a = 2
// 模板中的任意表达式:
val s2 = "${s1.replace("is", "was")}, but now is $a"
// 结果
a was 1, but now is 2
控制流逻辑
if条件表达式
fun maxOf(a: Int, b: Int) = if (a > b) a else b
while循环
val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
//do while循环
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在此处可见
when表达式
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
for循环
变量in集合
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
in的使用技巧
1 当作条件语句:x in 1..y+1 ,
val x = 10
val y = 9
//使用 *in* 运算符来检测某个数字是否在指定区间内:
if (x in 1..y+1) {
println("fits in range")
//检测某个数字是否在指定区间外:
if (list.size !in list.indices) {
println("list size is out of valid list indices range, too")
}
2 区间迭代
for (x in 1..5) {
print(x)
}
3 数列迭代
for (x in 1..10 step 2) {
print(x)
}
println()
for (x in 9 downTo 0 step 3) {
print(x)
}
返回和跳转
https://www.kotlincn.net/docs/reference/returns.html
- return。默认从最直接包围它的函数或者匿名函数返回。
- break。终止最直接包围它的循环。
- continue。继续下一次最直接包围它的循环。
任何表达式都可以用@来标记,为一个表达式加标签,只需要在其前加标签。限制break等的作用范围。
loop@ for (i in 1..100) {
for (j in 1..100) {
if (……) break@loop
}
}
return返回标签:
Kotlin 有函数字面量、局部函数和对象表达式。因此 Kotlin 的函数可以被嵌套。
防止表达式具体值的返回, 可以用标签限制返回值
Kotlin 有函数字面量、局部函数和对象表达式。因此 Kotlin 的函数可以被嵌套。 标签限制的 return 允许我们从外层函数返回。 最重要的一个用途就是从 lambda 表达式中返回。回想一下我们这么写的时候:
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return // 非局部直接返回到 foo() 的调用者
print(it)
}
println("this point is unreachable")
}
Target platform: JVMRunning on kotlin v. 1.3.72
这个 return 表达式从最直接包围它的函数即 foo
中返回。 (注意,这种非局部的返回只支持传给内联函数的 lambda 表达式。) 如果我们需要从 lambda 表达式中返回,我们必须给它加标签并用以限制 return。
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // 局部返回到该 lambda 表达式的调用者,即 forEach 循环
print(it)
}
print(" done with explicit label")
}
Target platform: JVMRunning on kotlin v. 1.3.72
现在,它只会从 lambda 表达式中返回。通常情况下使用隐式标签更方便。 该标签与接受该 lambda 的函数同名。
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调用者,即 forEach 循环
print(it)
}
print(" done with implicit label")
}
Target platform: JVMRunning on kotlin v. 1.3.72
或者,我们用一个匿名函数替代 lambda 表达式。 匿名函数内部的 return 语句将从该匿名函数自身返回
fun foo() {
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
if (value == 3) return // 局部返回到匿名函数的调用者,即 forEach 循环
print(value)
})
print(" done with anonymous function")
}
Target platform: JVMRunning on kotlin v. 1.3.72
请注意,前文三个示例中使用的局部返回类似于在常规循环中使用 continue。并没有 break 的直接等价形式,不过可以通过增加另一层嵌套 lambda 表达式并从其中非局部返回来模拟:
fun foo() {
run loop@{
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop // 从传入 run 的 lambda 表达式非局部返回
print(it)
}
}
print(" done with nested loop")
}
Target platform: JVMRunning on kotlin v. 1.3.72
当要返一个回值的时候,解析器优先选用标签限制的 return,即
return@a 1
意为“返回 1
到 @a
”,而不是“返回一个标签标注的表达式 (@a 1)
”。
参考链接: