在 2019 年 Google I/O 大会上,我们宣布今后将优先采用 Kotlin 进行 Android 开发,并且也坚守了这一承诺。Kotlin 是一种富有表现力且简洁的编程语言,不仅可以减少常见代码错误,还可以轻松集成到现有应用中。如果您想构建 Android 应用,建议您从 Kotlin 开始着手,充分利用一流的 Kotlin 功能。
kotlin developers 网站地址:developer.android.com/kotlin/lear...
常见用法文档:
1、openaidoc.org/kotlin/basi... 2、kotlinlang.org/api/core/ko...
Kotlin 优先意味着什么?

一、Kotlin 基本语法
1、变量声明
// 可变变量
var name = "Kotlin" name = "Java" // 可以重新赋值
// 不可变变量
val pi = 3.14 // pi = 3.1415 // 错误,val 变量不能重新赋值
// 显式类型声明
var age: Int = 25 var height: Double = 1.75 只需要认识到var 和val ,var 声明的变量就是可变的,val 声明的变量是不可变的,类似java 中的final
2、 基本数据类型
// 数字类型
val intNum: Int = 42
val longNum: Long = 42L
val doubleNum: Double = 3.14
val floatNum: Float = 3.14f
// 布尔类型
val isTrue: Boolean = true
val isFalse = false // 类型推断
// 字符类型
val letter: Char = 'A'
// 字符串 val str: String = "Hello"
val multiLineStr = """ This is a multi-line string """.trimIndent()
1)、由上面我们可以知道,在kotlin 中不存在数据类型的装箱或拆箱,简化了我的代码逻辑
在java 中 int 和 Interage 在kotlin 中就是一种表示 ->Int
2)、kotlin 中存在数据类型的自我推断,省去了java中的强制类型定义。 比如 比如:在java中,我们需要
ini
String name = "abc";
但是在kotlin中,我们只需要
ini
var name ="abc";
3、kotlin中函数的表达
是以fun 来定义的 eg:
kotlin
fun sum(a: Int, b: Int): Int {
return a + b
}
我们对比下,如果用java 来写
arduino
public int sum(int a, int b) {
return a + b;
}
注意kotlin 的函数中" : "后接返回值类型 如果你不需要返回值
kotlin
fun setName(a: String) {
name = a
}
typescript
public void setName(String a){
name = a;
}
4、kotlin 中 类和对象的表示
kotlin
// 类定义
class Person(val name: String, var age: Int) {
// 属性
var address: String = ""
// 方法
fun speak() {
println("$name is speaking")
}
// 初始化块
init {
println("Person initialized")
}
}
// 创建对象
val person = Person("Alice", 25)
person.age = 26 // 可变属性可以修改
// person.name = "Bob" // 错误,val 属性不可修改
person.speak()
我们发现kotlin中省去了new的关键字, 同时有init 这个代码,其实,这个init代码块不是必需的,你可以写,也可以不写,如果添加的话,相当于这个代码块中的代码会随着这个对象的创建后默认执行且只执行一次。
5、kotlin 中 ## 空安全
相对于java, 在java 中声明一个变量,
arduino
String name;
如果你稍不注意,这个变量在使用的时候,可能就是空的,编译器不会在编译的时候检测,这就会造成,当你运行程序的时候崩溃。koltin 的空安全,就是把这类问题,从运行期,提前到了编译器,让程序员在编译的时候,就能直接收到提示,此处是危险的,编译器直接就会报错
java
// 不可空类型
var a: String = "abc"
// a = null // 编译错误
// 可空类型
var b: String? = "abc"
b = null // 允许
// 安全调用
val length = b?.length // 如果 b 为 null,返回 null
// Elvis 操作符
val len = b?.length ?: -1 // 如果 b 为 null,返回 -1
// 非空断言
val l = b!!.length // 如果 b 为 null,抛出 NullPointerException
那么这里就要介绍kotlin "?"这个问号了,它就相当于java 中的 if(a == null), 又省了代码了,舒服,你想想,一个?能让你的代码减少多少次if(a == null) 或者 if(a != null), 俺们的时间也是宝贵的呀,编程生涯中,有多少时间浪费在判空上们,防御性编程。
是不是有些瞌睡,萌妹凝视
3、条件表达式
kotlin 中没有三元运算符了 java中的三元运算符还是挺便利的 eg:
css
int max = (a > b) ? a : b;
但是kotlin取消了这种写法,我个人认为,在kotlin中":"冒号这个符号还是挺特殊的,它在kotlin中代表了继承或者实现, 那么在kotlin中实现三元运算符的功能就是
css
val max = if (a > b) a else b
我们在java中习惯用switch -case 来进行判断分支 那么在kotlin中,有个更简单的写法:
perl
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
3,4->print("x == 5")
else -> print("x is neither 1 nor 2")
}
对比下,switch-case
csharp
switch (x) {
case 1:
System.out.print("x == 1");
break;
case 2:
System.out.print("x == 2");
break;
case 3:
case 4: // 多个case共享同一逻辑(对应Kotlin的3,4->)
System.out.print("x == 5"); // 注意:原Kotlin代码这里可能是笔误(3,4对应x==5)
break;
default: // 对应Kotlin的else
System.out.print("x is neither 1 nor 2");
break;
}
两者比较下,kotlin 的写法,不仅不需要写break,也不需要写";"
对于循环: java 常用的for(int i = 0; i < list.size(), i++), foreach,或者迭代器遍历,kotlin有封装充分的,对数据集合操作的各种便利的操作
scss
// for 循环
for (i in 1..5) print(i) // 输出 12345
for (i in 1 until 5) print(i) // 输出 1234
for (i in 5 downTo 1) print(i) // 输出 54321
for (i in 1..5 step 2) print(i) // 输出 135
// while 循环
while (x > 0) {
x--
}
// do-while 循环
do {
x--
} while (x > 0)
对于集合的操作,kotlin 里封装了太多的成品,非常好用,用起来,能节省很多时间(其实就是官方封装的一系列扩展函数)
集合操作符map
映射转换通过对另一个集合的元素应用函数的结果来创建集合。 基本的映射函数是 [map()
]
scss
val numbers1 = listOf(1, 2, 3)
println(numbers.map { it * it }) // [1, 4, 9]
scss
val numbers2 = listOf(1, 2, 3)
println(numbers.map { it * 2 }) // [2, 4, 6]
上面返回的numbers1 就是 [1,4,9],numbers2 返回的就是[2, 4, 6] ,map操作符就相当于对当前集合中的每个元素进行变换,同时返回一个新的集合
当然还有[mapIndexed()
],允许你在遍历的时候可以拿到每个元素的索引
kotlin
val fruits = listOf("苹果", "香蕉", "橙子", "草莓")
// 给每个水果添加编号(索引从1开始)
val numberedFruits = fruits.mapIndexed { index, fruit ->
"${index + 1}. $fruit" // index是从0开始的,+1转为自然序号
}
println(numberedFruits)
// 输出:[1. 苹果, 2. 香蕉, 3. 橙子, 4. 草莓]
再介绍一个[mapIndexedNotNull()
]
- 三功能合一 :同时实现「索引访问」+「元素转换」+「过滤空值」,等价于
mapIndexed { ... }.filterNotNull()
的简化版。 即按照索引遍历的同时,你可以进行元素转换,同时返回的结果过滤掉了空值。
scss
val numbers = listOf(10, 20, 30, 40, 50)
// 仅处理偶数索引(0、2、4)的元素,乘以10;奇数索引返回null(会被过滤)
val result = numbers.mapIndexedNotNull { index, num ->
if (index % 2 == 0) {
num * 10 // 非空结果:保留
} else {
null // 空结果:被过滤
}
}
println(result) // 输出:[100, 300, 500]
对于集合元素的map变换还有一些其他的方法,有兴趣可以再了解kotlinlang.org/api/core/ko...