本课程为极客时间上朱涛老师的《Kotlin编程第一课》的学习笔记
1.变量
- val 不可变,相当于Java中加了final
- var可变
/*
关键字 变量类型
↓ ↓ */
var price: Int = 100; /*
↑ ↑
变量名 变量值 */
由于Kotlin支持类型推导,所以还可以进一步略写
var price = 100 // 默认推导类型为: Int
PS:好习惯就是尽量用val而不是var,合理利用kotlin的优势,能避免很多问题
2.基础类型
Kotlin中,一起都是对象
Java中存在 int,short这样的基础类型;Kotlin则没有这些基础类型;
并且Java中有自动装包和自动拆包;这就是为了解决基础类型和数据类之间转换的问题;而Kotlin从设计之初就避免了这个问题
基础类型分为两类:
- 原始类型(Primitive Types):如int,long
- 包装类型(Wrapper Type):如Interger,Long
3.空安全
val i: Double = null // 编译器报错
这样的写法是不合理的,Kotlin会要求开发者在定义前指定变量是否为空;这种策略极大避免了空指针NullPointException;
所以正确的写法如下:
val i: Double = null // 编译器报错
val j: Double? = null // 编译通过
4.数字类型
Java可以隐藏式抓换数字类型,而kotlin更推崇显式转换
例如,下面的表达式在Java中是正常的
int i = 100;
long j = i;
但是在kotlin中就会报异常:
val i = 100
val j: Long = i // 编译器报错
需要更改为以下格式才行:
val i = 100
val j: Long = i.toLong() // 编译通过
特点就是:可读性更强,维护性更强;并且充分发挥了Kotlin没有基础类型的优势
5.布尔类型
Kotlin中布尔类型的变量,只有两种值,分别是true和false;这里主要讲Kotlin中的一些逻辑操作
- “&”代表“与运算”;
- “|”代表“或运算”;
- “!”代表“非运算”;
- “&&”和“||”分别代表它们对应的“短路逻辑运算”。
例如:
val i = 1
val j = 2
val k = 3
val isTrue: Boolean = i < j && j < k
6.字符
字符用于单个字符val c: Char = 'A'
但是下面的按照Java和C的方式写的代码,就会报错
val c: Char = 'A'
val i: Int = c // 编译器报错
原因就是前面隐式转换一样的问题,Kotlin并不支持隐式转换;所以正确的操作是这样的
val c: Char = 'A'
val i: Int = c.toInt() // 编译通过
7.字符串:String
字符串,顾名思意,就是一连串的字符。但是kotlin的拓展能力会令开发这觉得很方便
- 简洁模板
val name = "Kotlin"
print("Hello $name!")
/* ↑
直接在字符串中访问变量,这个特性在js,python已经存在;Java至今没有适配
*/
// 输出结果:
Hello Kotlin!
- 带方法的模板
val array = arrayOf("Java", "Kotlin")
print("Hello ${array.get(1)}!")
/* ↑
复杂的变量,使用${}
*/
// 输出结果:
Hello Kotlin!
- 原始字符串(解决转义的神器)
val s = """
当我们的字符串有复杂的格式时
原始字符串非常的方便
因为它可以做到所见即所得。 """
print(s)
8.数组
相对于Java,Kotlin中的数组会更丰富
- 使用arrayOf来创建数组
val arrayInt = arrayOf(1, 2, 3)
val arrayString = arrayOf("apple", "pear")
虽然 Kotlin 的数组仍然不属于集合,但它的一些操作是跟集合统一的。
val array = arrayOf("apple", "pear")
println("Size is ${array.size}")
println("First element is ${array[0]}")
// 输出结果:
Size is 2
First element is apple
9.函数(最高公民)
- 函数的声明
- 使用了 fun 关键字来定义函数;
- 函数名称,使用的是驼峰命名法(大部分情况下);
- 函数参数,是以 (name: String) 这样的形式传递的,这代表了参数类型为 String 类型;
- 返回值类型,紧跟在参数的后面;
- 最后是花括号内的函数体,它代表了整个函数的逻辑
/*
关键字 函数名 参数类型 返回值类型
↓ ↓ ↓ ↓ */
fun helloFunction(name: String): String {
return "Hello $name !"
}/* ↑
花括号内为:函数体
*/
上面的格式为标准格式,其实在实际使用会存在简化格式;如上面的可以简化为单一表达表函数
fun helloFunction(name: String): String = "Hello $name !"
而且在单一表达形式的时候,返回值类型也可以省略;这里也是利用了类型推导
fun helloFunction(name: String) = "Hello $name !"
10.函数的调用
- 标准的函数调用
helloFunction("Kotlin")
- 使用命名参数
helloFunction(name = "Kotlin")比较复杂的场景
使用场景
fun createUser(
name: String,
age: Int,
gender: Int,
friendCount: Int,
feedCount: Int,
likeCount: Long,
commentCount: Int
) {
//..
}
- 参数默认值
fun createUser(
name: String,
age: Int,
gender: Int = 1,
friendCount: Int = 0,
feedCount: Int = 0,
likeCount: Long = 0L,
commentCount: Int = 0
) {
//..
}
默认参数的好处就是如果不传入值,会填入默认值
11.流程控制
11.1 if
if语句,在程序中主要是用于逻辑判断,Kotlin中if与Java一致
val i = 1
if (i > 0) {
print("Big")
} else {
print("Small")
}
输出结果:
Big
当然这个是仿Java的写法,Kotlin还有更简洁的写法
val i = 1
val message = if (i > 0) "Big" else "Small"
print(message)
输出结果:
Big
Elvis表达式 :超强的可空判断
fun getLength(text: String?): Int {
return text?.length ?: 0
}
它的效果等同于
if (xxx != null) xxx else xxx
它的特点就在于:提高了的代码的可读性,也提升了编码效率
11.2when
when的使用场景在于,代码逻辑存在多个分支时,使用它是最稳妥的;个人感觉比if/else if/if的组合要好很多
val i: Int = 1
when(i) {
1 -> print("一")
2 -> print("二")
else -> print("i 不是一也不是二")
}
输出结果:
一
同样的,它也具备简写的方式
val i: Int = 1
val message = when(i) {
1 -> "一"
2 -> "二"
else -> "i 不是一也不是二" // 如果去掉这行,会报错
}
print(message)
注意:when必须要枚举完所有可能出现的参数,所以这里就不能去掉else;但是如果when条件已经枚举完;不需要写else的情况下时,需要特殊的操作(具体什么,后面会说)
11.3while 与 for
两者都是重复执行代码体内的参数,普while通写法与Java没什么区别
var i = 0
while (i <= 2) {
println(i)
i++
}
var j = 0
do {
println(j)
j++
} while (j <= 2)
输出结果:
0
1
2
0
1
2
但是for的语句就不相同,更多用于“迭代”的概念
val array = arrayOf(1, 2, 3)
for (i in array) {
println(i)
}
//上面的代码用来迭代打印array这个数组内所有的元素
迭代一个区间用到“..”来连接数值区间的两端
val oneToThree = 1..3 // 代表 [1, 3]
for (i in oneToThree) {
println(i)
}
输出结果:
1
2
3
甚至可以使用逆序迭代一个区间
for (i in 6 downTo 0 step 2) {
println(i)
}
输出结果:
6
4
2
0
这里只能如此定义(感觉怪怪的),而且“6..0”这样的定义是无效的