Osmanthus

空想具現化


  • 首页
  • 归档
  • 分类
  • 标签
  • 关于
  •   

© 2024 Homurax

UV: | PV:

Theme Typography by Makito

Proudly published with Hexo

Kotlin 基础01 - 变量、函数、逻辑控制

发布于 2020-04-06 Kotlin  Kotlin 基础 

变量

Kotlin 使用的是静态类型系统 (static type system),因为类型推断的语言特性,对于已声明并赋值的变量,它允许省略类型定义。

IDEA 中如果对一个变量的类型有疑问,可以单击变量名,并按 Control-Shift-P 组合键,会显示出变量的类型。

关键字

只能在变量前声明两种关键字

  • val value 的缩写,用来声明一个不可变的变量,初始赋值之后不可重新赋值。对应 Java 中的 final 变量
  • var variable 的缩写,用来声明一个可变的变量,初始赋值之后仍可重新复制。对应 Java 中的非 final 变量

对一个变量延迟赋值,Kotlin 就无法自动推导它的类型了,可以显式地声明变量类型

fun main() {
    println("Hello World")
    var a: Int = 10
    a *= 10
    println("a = " + a)
    println("a = $a")
}

数据类型

Java 和 Kotlin 数据类型对照

Java 基本数据类型 Kotlin 对象数据类型 数据类型说明
int Int 整形
long Long 长整形
short Short 短整形
float Float 单精度浮点型
double Double 双精度浮点型
boolean Boolean 布尔型
char Char 字符型
byte Byte 字节型

Kotlin 完全抛弃了 Java 中的基本数据类型,全部使用了数据对象类型。

val 的设计是为了解决 Java 中 final 关键字没有被合理使用的问题(大部分人没有主动使用)。永远优先使用 val 来声明一个变量,当 val 无法满足需求时再使用 var。

位运算

函数 描述 实例
Integer.toBinaryString 整数转二进制 Integer.toBinaryString(12)
shl(bitcount) 按位左移 1.shl(2)
1 shl 2
shr(bitcount) 按位右移 1.shr(2)
1 shr 2
inv() 按位取反 1.inv()
xor(number) 按位异或 42.xor(33)
42 xor 33
and(number) 按位与 42.and(10)
42 and 10

函数

Java 习惯叫做方法(翻译自 method),Kotlin 习惯叫做函数(翻译自 function)。

  • fun 是定义函数的关键字
  • fun 后面的是函数名
  • 参数列表,参数的声明格式参数名: 参数类型
  • 声明函数返回类型
import kotlin.math.max

fun main() {
    val a = 37
    val b = 40
    val value = largerNumber(a, b)
    println("The larger number is $value")
}

fun largerNumber(a: Int, b: Int): Int {
    return max(a, b)
}

函数的参数默认值

Kotlin 提供了给函数设定参数默认值的功能。

fun main() {
    printParams(10)
}

fun printParams(num: Int, str: String = "hello") {
    println("num is $num, str is $str")
}

如果改成给第一个参数设定默认值,模仿刚才的写法,编译器会认为想把字符串赋值给第一个 num 参数,从而报类型不匹配的错误

fun main() {
    // error! Type mismatch: inferred type is String but Int was expected
    printParams("world")
}

fun printParams(num: Int = 5, str: String) {
    println("num is $num, str is $str")
}

Kotlin 提供了通过键值对的方式来传参,不必按照函数参数列表中的参数顺序

fun main() {
    printParams(str = "world")
    printParams(str = "world", num = 100)
    printParams(num = 1000, str = "world")
}

fun printParams(num: Int = 5, str: String) {
    println("num is $num, str is $str")
}

单表达式函数

函数的语法糖,单表达式函数 (只有一个表达式语句,或者说都只有一条求值语句) 的返回类型、花括号、返回语句都可以省掉。允许不必编写函数体。

fun largerNumber(a: Int, b: Int) = max(a, b)

特殊字符命名的函数

Kotlin 可以定义或调用以空格和其他特殊字符命名的函数,函数名要用一对反引号括起来。

fun main() {
    // Call
    `**~prolly not a good idea!~**`()
}

fun `**~prolly not a good idea!~**`() {
    println("**~prolly not a good idea!~**")
}

Kotlin 如此设计的原因

  • Kotlin 和 Java 各自有不同的保留关键字,不能用作函数名。使用反引号括住函数名就能避免任何潜在冲突。
  • 通过使用反引号特殊语法,可以在测试文件中使用更直观易懂的函数名。比单词以驼峰形式拼接的命名规则更加直观。

Unit 函数

Kotlin 使用 Unit 返回类型表明这样一件事:函数没有返回值。函数定义中如果没使用 return 关键字,那暗含的意思就是,Unit 就是这个函数的返回类型。

对于 Java 中的 void 关键字,意思是 “没有返回类型,不会带来什么,忽略它”。这似乎流于表面:如果函数不返回任何东西,就忽略类型。void 这种解决方案无法解释现代语言的一个重要特征:泛型。作为现代编译语言的一个特征,泛型让编程更为灵活。

Nothing 类型

Kotlin 还有一种叫作 Nothing 的类型。类似于 Unit,Nothing 类型的函数也不返回任何东西。

在编译器看来,Nothing 就意味着函数不可能成功执行完成,它要么抛出异常,要么因某个原因再也返不回调用处。

TODO 函数的任务就是抛出异常,返回Nothing类型。

看到 TODO 函数的 Nothing 类型,编译器就知道它肯定会抛错,所以就不会越过 TODO 函数去检查函数体内的返回类型,因为函数是不可能返回数据的。能通过编译器的检查,开发者就可以暂不具体实现函数,而是继续把该函数依赖的前提任务处理完毕。

逻辑控制

顺序语句、条件语句和循环语句

if 条件语句

Kotlin 中的 if 语句比 Java 有一个额外的功能,可以有返回值。

fun largerNumber(a: Int, b: Int): Int {
    return if (a > b) {
        a
    } else {
        b
    }
}

if 语句使用每个条件的最后一行作为返回值。

fun largerNumber(a: Int, b: Int) = if (a > b) a else b

when 条件语句

if、when 都可以有返回值,when 比 Java 中的 switch 要好用。when 的逻辑表现力更强,且配合单行代码函数的语法糖使用,代码更简洁。

fun getScore(name: String) = when (name) {
    "Tom" -> 86
    "Jim" -> 77
    "Lily" -> 100
    else -> 0
}

when 语句允许传入一个任意类型的参数,然后在 when 的结构体中定义一系列的条件,执行逻辑只有一行时,{}可以省略。

匹配值 -> { 执行逻辑 }

when 语句允许进行类型判断。

fun checkNumber(num: Number) = when (num) {
    is Int -> println("number is Int")
    is Double -> println("number is Double")
    else -> println("number not support")
}

is 相当于 Java 中的 instanceof 关键字。

when 语句还有一种不带参数的用法,不常用但是能发挥出扩展性。

fun getScore(name: String) = when {
    name.startsWith("Tom") -> 86
    name == "Jim" -> 77
    name == "Lily" -> 100
    else -> 0
}

Kotlin 中判断字符串或者对象相等可以直接使用 == 。

循环语句

while 循环与 Java 中没有任何区别,跳过。

Java 中的 for-i 循环被舍弃了,for-each 循环被增强,变为 Kotlin 中的 for-in 循环。

区间

Kotlin 中使用 a .. b 可以创建一个双端闭区间([a, b]),使用 a until b 可以创建一个单端闭区间([a, b))。

fun main() {
    for (i in 0..10) {
        println(i)
    }
    for (i in 0 until 10) {
        println(i)
    }
}

.. 与 until 都要求左端小于等于右端,如果需要降序区间,可以使用 downTo 来创建。比如 10 downTo 1 相当于 [10, 1] 的降序区间。

fun main() {
    for (i in 10 downTo 1) {
        println(i)
    }
}

for-in 每次循环时都会在区间范围内递增1,类似于 for-i 中的 i++ 。

如果想多跳过其中的一些元素,可以使用 step 关键字。

fun main() {
    for (i in 0..10 step 2) {
        println(i)
    }
    for (i in 0 until 10 step 3) {
        println(i)
    }
    for (i in 10 downTo 1 step 4) {
        println(i)
    }
}

for-in 没有传统的 for-i 灵活,但是简单好用,覆盖了绝大部分使用场景。如果一些特殊场景无法实现, 可以改用 while 循环的方式进行。

 上一篇: Kotlin 基础02 - 类、对象、初始化 下一篇: Java 类型系统 

© 2024 Homurax

UV: | PV:

Theme Typography by Makito

Proudly published with Hexo