Kotlin学习笔记(持续更新)

Kotlin学习笔记

1.语言特性

Kotlin与Java完全互操作
扩展函数与扩展属性

为String添加firstChar函数

fun String.firstChar():String{
	if(this.length() == 0){
		return "";
	}
	return this[0].toString()
}

在代码中直接调用该函数

"abc".firstChar()
不可空类型与空安全

引入不可空类型与可空类型
编译期通过类型是否匹配来检查空指针异常
提供Elvis操作符、安全调用符等极简的语法格式

不可空类型 var a = “abc”,则a = null 会报错,因为a声明了不可空类型String
可空类型 var b:String? = “abc” 调用b.length 还是会报错,需要使用安全调用符(?.)或断言调用符(!!)
—>b?.length or b!!.length

一等函数支持

Kotlin中函数是第一等类型,一个函数可以作为另一个函数的返回值,称为一等函数支持

智能类型判断

在声明变量时未显式指定其类型,编译器其中会自动推断其类型

2.Kotlin语法基础

2.1 变量与标识符

Kotlin中,所有的变量都是引用类型,命名同Java遵循驼峰式命名法

val:只读,仅能一次赋值(可以带来可预测的行为,线程安全)
var:可写,可以被多次赋值

val a:Int = 1 //用val声明一个不可变的常量a
//编译器能够自动推断类型,所以可以省去类型代码
val a = 1
a++ -> error: var cannot be reassigned //a不可以重新赋值

var b = 1 //用var声明一个可变的变量b
b = b + 1 //b可以被多次赋值
2.2 关键字与修饰符

一些关键字不能被用作变量名

2.3 流程控制语句

分支语句 if、when
循环语句 while、for
跳转语句 return、break、continue、throw

2.3.1 if表达式
fun main(args : Array<String>){
	println(max1(1,2))
}

fun max1(a : Int, b: Int): Int{
	//表达式返回值
	val max = if(a>b) a else b //表达式返回值,相当于Java三元表达式
	return max
}

fun max2(a : Int, b : Int): Int{
	//代码块返回值
	val max = if(a > b){
		println("最大数是" + a)
		a	//if作为代码块时,最后一行为其返回值
	}else{
		println("最大数是" + b)
		b
	}
	return max
}

ps. if后的括号不能省略,括号内表达式的值必须式布尔型

e.g 用if…else语句判断年份是否是闰年

fun ifLeapYear(year : Int) : Boolean{
	var isLeapYear : Boolean //声明一个局部变量
	if(year % 4 == 0 && year % 100 != 0 ) || (year % 400 == 0){
		//判断是否是闰年
		isLeapYear = true
	}else{
		isLeapYear = false
	}
	return isLeapYear
}

fun main(args : Array>String){
	println(isLeapYear(2017)) //不是闰年
	println(isLeapYear(2018)) //是闰年
}
2.3.2 when表达式

类似于switch…case…,对所有分支进行检查直到有一个条件被满足。

fun caseWhen(obj : Any?){
	val x = "123"
	when(x){
		0,1,2,3,4,5,6,7,8,9 -> println("${obj} ===> 这是一个0-9的数字")
		"hello" -> println("${obj} ===> 这是一个字符串hello") //is 类型判断
		is Char -> println("${obj} ===> 这是一个Char类型数据")
		parseInt(x) -> println("可以用任意表达式(而不只是常量)作为分支条件")
		in 1...10 -> println()
		else -> println("else类似于Java中switch...case...语句中的default")
	}
}

fun main(args : Array<String>){
	caseWhen(7)
	caseWhen("hello")
	caseWhen('a')
	caseWhen(null)
}

也可以检测在(in)或者不在(!in)一个区间或集合中

val x = 1
val validNumbers = arrayOf(1,2,3)
when(x){
	in 1..10 -> println("x is in the range")
	in validNumbers -> println("x is valid") 
	!10..20 -> println("x is outside the range")
	else -> println("none of the above")
}

用when语句写一个阶乘函数

fun fact(n : Int): Int{
	val result = 1
	when(n){
		0,1 -> result = 1
		else -> result = n * fact(n-1)
	}
	return result
}

fact(10)  //3628800
2.3.3 for循环

for循环可以对任何提供迭代器(iterator)的对象进行遍历

//for in 循环
for(item in collection){
	println(item);
}

遍历数组或list时

for(i in array.indices){		//array.indices持有数组的下标列表
	println(array[i]);
}

for((index, value) in array.withIndex()){
	println("数组位置$index的值是$value");
}

范围(Ranges)表达式也可用于for循环中

for(i in 1..10){		//1..10等价于1.rangeTo(10)
	println(i)
}
//简写如下
(1..10).foreach(){	println(it) }

e.g 输出1-n阶乘的和(1! + 2! + … +n!)

public void sunFact(n : Int){
	var sum = 0
	for(i in 1..n){
		sum += fact(i)
	}
}
2.3.4 while循环

while与do…while循环语句的使用方式与C、Java语言基本一致

fun main(args : Array<String>){
	var x = 10
	while(x > 0){
		x-
		println(x)
	}

	var y = 0
	do{
		y = y + 1
		println(y)
	}while(y > 10)
}
2.3.5 break和continue

问题场景1:打印数字1~10,只要遇到偶数就结束打印

for(i in 1..10){
	println(i)
	if(i % 2 == 0){
		break
	}
}

问题场景2:打印1~10中的奇数

//正常
for(i in 1..10){
	if(i % 2 != 0){
		println(i)
	}
}

//使用continue
for(j in 1..10){
	if(j % 2 == 0){
		continue
	}
	println(j)
}
2.3.6 return返回

在Kotlin中,出了表达式的值,有返回值的函数都要求显式使用return语句返回其值

fun sum(a : Int, b : Int) : Int{
	return a + b	//这里的return不能省略
}

fun max(a : Int, b : Int):Int{
	if(a > b){
		return a	//这里的return不能省略
	}else{
		return b	//这里的return不能省略
	}
}

Kotlin中可以直接用“=”来返回一个函数的值,这样的函数称为函数字面量,示例如下:

fun sum(a : Int, b : Int) = a + b
fun max(a : Int, b : Int) = if(a > b) a else b
val sum1 = fun(a : Int, b = Int) = a + b	//使用fun关键字声明了一个匿名函数,并且直接使用表达式来实现函数
val sum2 = fun(a : Int, b = Int) = {a + b}	//后面函数体语句中有大括号{}则返回的是一个Lambda表达式
val sumf(kotlin.Int, kotlin.Int) -> () -> kotlin.Int //sumf是一个高阶函数类型,{a+b}的类型是从(kotlin.Int, kotlin.Int)到()->kotlin.Int的映射函数
>>> sumf(1,1) 	//调用sumf(1,1),返回的是一个函数
() -> kotlin.Int 	//sumf(1,1)的返回值是一个函数() -> kotlin.Int,而不是具体的数值
sumf(1,1).invoke()	//使用invoke函数实现真正调用函数
sumf(1,1)()		//使用括号()调用函数,与invoke()等价

在Kotlin中,()操作符对应的是类的重载函数,如invoke().两者是等价的

你可能感兴趣的:(Android)