简单介绍
定义包
包的声明应处于源文件顶部:
package my.demo
import java.util.*
//...
目录与包的结构无需匹配:源代码可以放在文件系统的任意位置。
定义函数
带有两个Int
参数,返回Int
函数:
fun sum (a:Int,b:Int):Int{
return a+b
}
将表达式作为函数体,返回值类型自动推送的函数:
fun sum (a:Int,b:Int) = a + b
函数返回无意义的值:
fun printSum(a:Int,b:Int){
println("sum $a and $b is ${a+b}")
}
Unit
返回类型可以省略:
fun printSum(a:Int,b:Int){
println("sum of $a and $b is ${a+b}")
}
定义变量
定义只读局部变量使用关键字val
定义。只能为其赋值一次。
val a:Int = 1 //立即赋值
val b = 2 //自动推出‘Int’类型
val c:Int //如果没有赋初值,则不能省略
c = 2 //明确赋值
可重新赋值的变量使用var
关键字:
var x = 5
x += 1
顶层变量:
val PI = 3.14
var x = 0
注释
正如Java,Kotlin支持行注释及块注释。
// 这是一个行注释
/* 这是一个多行的
块注释。*/
与Java不同的是,Kotlin的块注释可以嵌套。
使用字符串模板
使用字符串模板的符号为($
)。在$
符号后面加上变量名或大括号中的表达式
var a = 1
val s1 = "a is $a"
// 模板中的简单名称
a = 2
val s2 = "${s1.replace("is","was")},but now is $a"
//模板中的任意表达式
println(s2)
执行结果:
a was 1, but now is 2
声明可空变量
在Kotlin中当我们不确定某个属性或变量一定不为空时,我们就把它声明为可空变量.
可空变量的特点:
- 在声明的时候一定要用标准的声明格式定义。不能用可推断类型的简写;
- 变量类型后面的
?
符号不能省略。不然就和普通的变量没区别了; - 其初始化的值可以为
null
或确定的变量值。
class Test{
//声明可空变量
var a:Int? = 0;
val b:Int? = null;
}
常量的用法
在Kotlin中val
修饰的还不是常量,他只是个不能修改的变量。常量的定义还需要再val
关键字前加上const
关键字。即:
const val NUM_A = 6
其特点:const
只能修饰val
,不能修饰var
。
声明常量的三种方式:
- 在顶层声明;
- 在
object
修饰的类中声明,在kotlin
中称为对象声明; - 在伴生对象中声明。
例如:
// 1.顶层声明
const val Str_A :String = "顶层声明"
// 2.在object修饰的类中
object TestConst{
const val Str_B = "object修饰的类中"
}
// 3.在伴生对象中
class TestClass{
companion object{
const val Str_C = "在伴生对象中"
}
}
数据类型
数值类型
1. 数字的内置类型
Byte
=> 字节 => 8位Short
=> 短整型 => 16位Int
=> 整型 => 32位Long
=> 长整型 => 64位Float
=> 浮点型 => 32位Double
=> 双精度浮点型 => 64位
注意:
Kotlin不支持八进制数
3. 数字类型字面常量的下划线
作用:分割数字进行分组,使数字常量更易读
例如:
val oneMillion = 1_000_000
val phoneNum = 155_0746_2014
4. 装箱与拆箱
装箱就是值类型转换为object类型,拆箱相反:object转化为值类型。在kotlin
中,存在数字的装箱,但是没有拆箱。因为kotlin
是没有基本数据类型的,Kotlin
是万物皆对象的原则。
在kotlin
中要实现装箱操作,首先要了解可空引用。即类似Int?
(只限数值类型)此类的:
val numValue:Int = 1
// 装箱的过程,装箱后其值是没有变化的
val numValueBox:Int = numValue
两个数值的比较
- 判断两个数值是否相等
==
- 判断两个数值在内存中的地址是否相等
===
5. 转换
显式转换
较小的类型不会被隐式转换位更大的类型,故而系统提供了显式转换:
toByte()
=> 转换为字节型toShort()
=> 转换为短整型toInt()
=> 转换为整型toLong()
=> 转换为长整型toFloat()
=> 转换为浮点型toDouble()
=> 转换为双精度浮点型toChar()
=> 转换为字符型toString()
=> 转换为字符串型
隐式转换
类型是从上下文推断出来的,即算术运算则被重载为适当的转换:
val num = 30L + 12 println(num) // 30L + 12 -> Long + Int => Long
6. 位运算符
// 。。。。。
布尔类型
1. 关键字
Boolean
关键字表示布尔类型,并且其值有ture
和false
var isNum:Boolean
isNum = false
2. 逻辑操作符
- ‘||’ => 逻辑或
- ‘&&’ => 逻辑与
- ‘ ! ’ => 逻辑非
字符型
1. 关键字
Char
表示字符型,字符变量用单引号(‘’)表示。并且不能直接视为数字,不过可以通过显式转换为数字:
var char_1:Char
char = 'a'
char = 1 //报错
2. 显示转换为其他类型
字符型的变量不仅会可以转换为数字,同时也可转换为其他类型:
var var1 = char_1.toByte()
var var2 = char_1.toInt()
//...
除了类型转换,当变量为英文字母时还支持大小写转换:
var charA:Char = 'a'
var charB:Char = 'B'
var result:Char
result = charA.toUpperCase() //转换为大写
result = charB.toLowerCase() //转换为小写
3. 字符转义
\t
=> 制表符\n
=> 换行符\b
=> 退格键\r
=> 回车键\\
=> 反斜杠\'
=> 单引号\$
=> 美元符号- **其他的任何字符请使用Unicode转义序列语法,例如:’\uFF00’
字符串类型
1. 关键字
String
表示字符串类型。其实不可变的。所以字符串的元素可以通过索引操作的字符:str[index]
来访问。可以使用for
循环迭代字符串:其中str[index]
中的str
要为目标字符串,index
才能为索引:
val str:Sting = "kotlin"
//迭代
for (s in str){
print(s)
print("\t")
}
2. 字符串字面量
在Kotlin
中,字符串字面量有两种类型:
- 包含转义字符的字符串,转义包括(\t, \n等),不包括转义字符串的也同属此类型
- 包含任意字符的字符串,有三重引号(
"""..."""
)表示
数组型
Kotlin中
数组由Array<T>表示
- 创建数组的三个函数:
arrayOf()
arrayOfNulls()
- 工厂函数(
Array()
)
1. arrayOf()
创建一个数组,参数是一个可变参数的泛型对象:
val arr1 = arrayOf(1,2,3,4,5)
for (v in arr1){
print(v)
print("\t")
}
2. arrayOfNulls()
用于创建一个指定数据类型且可以为空元素的,给定元素个数的数组:
var arr2 = arrayOfNulls<Int>(3)
// 若不予数组赋值则arr3内元素皆为null
3. 工厂函数
- 使用工厂函数
Array()
,它使用数组大小和返回给定其索引的每个数组元素的初始值的函数。 Array()
=> 第一个参数表示的个数,第二个参数则为使用其下标组成的表达式
var arr3 = Array(5,{index -> (index*2).toString()})
for (v in arr4){
print(v)
print("\t")
}
执行结果:
0 2 4 6 8
4. 原始类型数组
kotlin
还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:
ByteArray
=> 表示字节型数组ShortArray
=> 表示短整型数组IntArray
=> 表示整型数组LongArray
=> 表示长整型数组BooleanArray
=> 表示布尔型数组CharArray
=> 表示字符型数组FloatArray
=> 表示浮点型数组DoubleArray
=> 表示双精度浮点型数组
Kotlin
不支持字符串类型这种原始类型的数组
var intArr:IntArray = intArrayOf(1,2,3,4,5)
var charArr:CharArray = charArrayOf('a','b','c','1','2')
控制语句
if语句
kotlin
中的if
语句很灵活,除了普通的判断,还可以实现表达式(实现三元运算符),及作为一个块的作用
1. 传统写法
var numA = 2
if (numA == 2){
println($numA)
}else{
println($numA-1)
}
2. Kotlin
中的三元运算符
在Kotlin
中其实不存在三元运算符(condition ? then : else)这种运算,那是因为if语句的特性:if
表达式会返回一个值,所以不需要三元运算符。
var numB:Int = if (numA > 2) 3 else 5
println(numB)
3. 作为一个块结构,并且最后一句表达式为块的值
var numA:Int = 2
var numC:Int = if(numA > 2){
numA = 10
numA
}else if (numA == 2){
numA = 20
numA
}else{
numA = 30
numA
}
for语句
for
循环提供迭代器用来遍历任何东西for
循环数组被编译为一个基于索引的循环,它不会创建一个迭代器对象
规则
递增
关键字:
until
范围:
until[n,m]
=> 大于等于n,小于m例如:
// 循环5次,且步长为1的递增 for (i in 0 until 5){ print(i) }
递减
- 关键字:
downTo
范围:
downTo[n,m]
=> 大于等于n,小于等于m,n > m例如:
// 循环5次,且步长为1的递减 for(i in 15 downTo 11){ print(i) }
- 关键字:
符号(
..
)表示递增循环的另外一种操作
使用符号
..
范围:
..[n,m]
=> 即大于等于n,小于等于m
和
until
有区别,但更为简便,且范围不同例如:
for (i in 20..25){ print(i) }
设置步长
关键字:
step
例如:
for (i in 10 until 16 step 2){ print(i) }
遍历字符串
例如:
for (i in "asdfghjk"){
print(i)
}
遍历数组
例如:
var arrayList = arrayOf(1,3,5,7,9)
for (i in arrayList){
print(i)
}
var arrayList = arrayOf(1,3,5,7,9)
for (i in arrayListTwo.indices){
println("arrayList[$i] => " + arrayList[i])
}
var arrayList = arrayOf(1,3,5,7,9)
for ((index,value) in arrayList.withIndex()){
println("index => $index \t value => $value")
}
使用列表或数组的扩展函数遍历
- 数组或列表有一个成员或扩展函数
iterator()
实现了Iterator<T>
接口,且该接口提供了next()
与hasNext()
两个成员或扩展函数 - 其一般和
while
循环一起使用
例如:
var arrayList = arrayOf(2,'a',3,false,9)
var iterator: Iterator<Any> = arrayList.iterator()
while (iterator.hasNext()){
println(iterator.next())
}
when语句
when
语句类似于C类语言中的switch
语句,不过比它更强大。
实现switch语句功能
when(5){
1 -> {
print("1")
}
2 -> {
print("2")
}
esle -> {
print("5")
}
}
与逗号结合
when(1){
// 即值为1,2,3时都输出1
1,2,3 -> {
print("1")
}
else -> {
print("0")
}
}
条件可以使用任意表达式
var num:Int = 5
when (num > 5){
true -> {
print("num > 5")
}
false -> {
print("num < 5")
}
else -> {
print("num = 5")
}
}
检查值是否存在于集合或数组中
操作符
in
在!in
不在
限定:只适用于数值类型
例如:
var arrayList = arayOf(1,2,3,4,5)
when(1){
in arrayList.toIntArray() -> println("1 存在于arrayList数组中")
in 0 .. 10 -> println("1 属于0~10中")
!in 5 ..10 -> println("1 不属于5~10中")
else -> println("都错了!")
}
检查值是否为指定类型的值
操作符
- 是
is
- 不是
!is
- 是
注意:
kotlin
的智能转换可以访问类型的方法和属性
例如:
when("abc"){
is String -> println("是字符串")
else -> println("不是字符串")
}
//智能转换
var a:Int = 2
when(a){
!is Int -> println("$a 不是一个整型的数")
else -> {
a = a.shl(2)
println("a => $a")
}
}
不使用表达式的when语句
表示为最简单的布尔表达式
var array = arrayOfNulls<String>(3)
when{
true -> {
for (i in array){
print(" $i \t")
}
println()
}
else -> {
}
}
其它语句
while语句
do while语句
跳转语句:return,break,continue
与C类语言一致,不做赘述。
操作符
一元操作符
简单一元
操作符 | 重载 |
---|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
复杂一元
操作符 | 重载 | 表示 |
---|---|---|
a++ | a.inc() | a = a.also{ a.inc() } |
a– | a.dec() | a = a.also{ a.dec() } |
++a | a.inc() | a = a.inc().also{ a = it } |
–a | a.dec() | a = a.dec().also{ a = it } |
二元操作符
简单二元
操作符 | 重载 |
---|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.tiems(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
a .. b | a.rangTo(b) |
复杂二元
操作符 | 表示 | 重载 |
---|---|---|
a += b | a = a + b | a = a.plus(b) |
a -= b | a = a - b | a = a.minus(b) |
a *= b | a = a * b | a = a.tiems(b) |
a /= b | a = a / b | a = a.div(b) |
a %= b | a = a % b | a = a.rem(b) |
区间操作
区间操作符:..
,注意两个操作数都是整型
操作符 | 表示 | 重载 |
---|---|---|
a .. b | a 到 b 中间的值 | a.rangeTo(b) |
进阶操作
可空类型,空安全
定义一个可空类型的变量
修饰符 变量名 : 类型? = 值
判断可空类型的两种方式
if…else… 判断
使用符号
?.
判断该符号的用法为:
可空类型变量?.属性/方法
。如果可空类型变量为null是,返回null;这种方法大量用于链式操作的用法中,能有效避免
空引用异常
,因为只要链式中有一个null
,则整个表达式都为null
。