Kotlin学习笔记(一)

本笔记是基于李刚的《Kotlin讲义》整理出来的,若有错误欢迎指出。

一、基础语法

1、概述

1.1 注释

单行注释: //
多行注释:/*...*/
文档注释:/**...*/

1.2 变量

可以使用val|var variableName[: type] [= initData]声明变量,其中val声明的变量是值不可变的。==必须指定变量类型或初始值==。

var a = 11 //指定初始值
var b: Int //指定变量类型
var c: Int = 1;//指定初始值和变量类型
val name = 'yaohuix' //指定常量,值不可变

Kotlin并不要求语句以分号结尾

2、类型

2.1 整型

支持Byte、Short、Int、Long四种整型。与Java不同的是,Kotlin的整型不是基本类型,而是引用类型(类似Java的包装类),继承自Number类。另外,Kotlin是null安全的语言,所以Byte、Short、Int、Long型变量都不能接受null值,要存储null值,应该使用Byte?、Short?、Int?、Long?类型。

普通类型的整型变量会被映射成Java的基本类型,带"?"的整型变量会被映射成基本类型的包装类

Kotlin允许已有的类型后添加"?"来支持赋予null值

var p1: Int = 11
var p2: Int = 11
println(p1 === p2) //基本类型的比较,输出true
var p3: Int? = 11
var p4: Int? = 11
println(p3 === p4) //引用类型的比较,输出false

支持的字面值有3种:

  • 二进制:0b或0B开头
  • 十进制:最普通的整数值
  • 十六进制:0x或0X开头
val p1 = 1_000_000 //允许增加下划线作为分隔符
var p2 = 0010000 //允许前面添加额外的零

Kotlin不支持八进制

2.2 浮点数

支持Float和Double两种类型。Kotlin还额外提供了3个特殊的浮点型数值:正无穷大负无穷大非数。正数除以0.0得到正无穷大,负数除以0.0得到负无穷大,0.0除以0.0或负数开方得到非数。

2.3 字符型

有三种表示形式:

  • 'A'
  • '\n'
  • '\uXXXX'

Kotlin的Char型只是字符型,不能直接当整型使用

2.4 字符串

与java不同的是,Kotlin允许s[i]来访问索引处的字符,也支持三引号表示的原始字符串,允许使用${}在字符串中嵌入变量或者表达式

var str = "Hello World"
println(str[1]) //e

//原始字符串可以包含换行和任意文本
//使用竖线(|)作为边界符,竖线之前的内容将全部去掉
var text = """
    |人间清暑殿
    |天上广寒宫
"""

//字符串模板
var price = 12
var bookPrice = "书本的价格是${price*5}元"

3、null安全

可空类型:比如 Int?
非空类型:比如 Int

Kotlin对可空类型做了限制,若不加任何处理,==可空类型不允许直接调用方法,访问属性==。

var aStr: String = "Hello"
var bStr: String? = "Hello"
aStr = null //错误
bStr = null //正确
println(aStr.length) //编译通过
println(bStr.length) //编译失败

如何调用可空类型?有以下两种方式:

//先判断后使用
var b: String? = "yao"
var len = if (b != null) b.length else -1
//安全调用
println(b?.length)

需要注意的是,对于可空的Boolean类型而言,它可接受3个值:true、false或null。因此对Boolean?进行判断时,要显示的与true、false值进行比较

var b: Boolean? = null
//以下语句将报错
if(b){}
//正确的做法
if(b == true){}
安全调用

?.

var b: String? = "Hello"
println(b?.length)
Elvis运算

?:
其实就是if else的简化写法,它的含义是左边的表达式不为null,返回左边的表达式,否则返回右边的表达式

var b: String = "Hello"
var len = b?.length ?: -1
强制调用

!!.
可能引发空指针

var b: String = "Hello"
var len = b!!.length

4、类型别名

类似C语言的typedef功能,可以为已有的类型指定另一个可读性更强的名字。语法格式为:typealias 类型别名 = 已有类型

typealias NodeSet = Set //指定别名
var set: NodeSet //声明变量

很多时候,我们可以定义别名来为内部类取一个更短的名字

class A{
    inner class Inner
}
typealias AInner = A.Inner
var a: AInner 

5、运算符

5.1 支持的运算符

Kotlin的运算符都是以方法的形式来实现的,也就是说只要我们为某类型实现了特定的方法,就可以对该类型对象用运算符进行"运算"。Kotlin不支持Java的三目运算符,使用了if else进行代替。

单目前缀运算符

+、-、!

运算符 对应方法
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
自加、自减运算符

++、--

运算符 对应方法
a++ a.inc()
a-- a.dec()
双目算术运算符

+、-、*、/、%、..

运算符 对应方法
a+b a.plus(b)
a-b a.minus(b)
a*b a.times(b)
a/b a.div(b)
a%b a.rem(b)
a..b a.rangeTo(b)
in和!in运算符

String类型就实现了contains()方法

var str = "hello world"
println("hello" in str)
运算符 对应方法
a in b b.contains(a)
a !in b !b.minus(a)
索引访问运算符
运算符 对应方法
a[i] a.get(i)
a[i,j] a.get(i,j)
a[i]=b a.set(i,b)
a[i,j]=b a.set(i,j,b)
调用运算符
运算符 对应方法
a() a.invoke()
a(b) a.invoke(b)
广义赋值运算符
运算符 对应方法
a+=b a.plusAssgin(b)
a-=b a.minusAssign(b)
a*=b a.timesAssign(b)
a/=b a.divAssign(b)
a%=b a.remAssign(b)

这种广义运算符有点特殊,比如a+=b,实际上相当于a=a+b,因此在程序中进行a+=b运算时,并不需要一定有plusAssign方法。

编译器会先判断是否存在plusAssign方法,如果存在,则必须plus方法不存在且plusAssign方法没有返回值,否则编译报错。然后执行plusAssign方法。否则执行a=a+b。

相等与不等运算符

== 、!=

运算符 对应方法
a==b a?.equals(b)?:(b===null)
a!=b !(a?.equals(b)?:(b===null))

Java中的"=="和"!="则由Kotlin中的"==="和"!=="代替

比较运算符
运算符 对应方法
a>b a.compareTo(b)>0
a a.compareTo(b)<0
a>=b a.compareTo(b)>=0
a<=b a.compareTo(b)<=0
5.2 区间运算符 重要

可以理解为List

含义 运算符
闭区间 2..5
半开区间 2 until 4 (不包括4)
反向区间 5 downTo 2
区间步长 5 downTo 2 step 2
var range1 = 2..6 //定义了一个范围对象
var range2 = 6 downTo 2
var range3 = 2 until 5
var range4 = 7 downTo 1 step 3

6、流程控制

6.1 分支结构
if分支

Kotlin的if分支既可以做为语句使用,也可以作为表达式使用。当作为表达式时,最后一条语句将作为表达式的值。

var age = 18
var str = if(age>20){
    "age大于20"
}else if(age<20){
    "age小于20"
}else{
    "age等于20"
}
when分支

when分支取代了Java中的switch语句

var score = 'A'
when (score) {
    'A' -> println("优秀")
    'B','C' -> println("良好")
    else -> println("差")
}

when分支的改进:

  • 可以匹配多个值
  • 分支的值不要求是常量,可以是任意的表达式
  • 条件表达式的类型没有要求,只要条件表达式与某个分支的值通过"=="比较返回true。

与if分支相同,when分支也可以作为表达式。

使用in,!in运算符,检查是否位于指定的区间或集合。

var str = when(age){
    in 10..25 -> "少年"
    else -> "其他"
}

使用is,!is运算符,检查表达式是否为指定类型

fun realPrice(inputPrice: Any) = when(inputPrice){
    is String ->inputPrice.toDouble()
    is Int ->inputPrice.toDouble
    else -> 0.0
}

取代if..else if链

var age = 5
when{//不再需要条件表达式
    age==5 -> print("五岁")
    age==10 -> print("十岁")
    else -> print("错误")
}
6.2 循环结构

Kotlin也支持while,do..while的循环结构,此外还支持for-in循环

for-in循环

专门用于遍历范围、List、Map和String。可遍历任何可迭代对象。可迭代对象是指该对象包含一个iterator()方法,且该方法的返回对象具有next()和hasNext()方法。

注意,此时不允许对被迭代对象进行数据变更

for(i in 2 until 10){
}

基础语法就先到这里,下一篇将介绍Kotlin中的数组和集合

你可能感兴趣的:(Kotlin学习笔记(一))