常量
- val = value,值类型,不能被重复赋值,类似于Java的final(但不等同,可通过字节码查看区别)。
- 举例:
运行时常量:val x = getX()
编译期常量:const val x = 2//可提高代码的执行效率
变量
- var = variable
- 举例:
var x = "hello World"//定义变量
x = "hello China" //再次赋值
类型推导
- 编译器可以推导量的类型
val str = "hello"//推导出类型是String
val b = 5//Int 类型
val a = getStr()+5//String类型
函数
- 函数定义
- fun 函数名(参数列表:参数类型):返回值类型{
//函数体
}
fun sum(num1:Int,num2:Int):Int{
return num1+num2
}
没有返回值时可以不写返回值类型,也可以写Unit
fun sayhello(name:String) {
Println("Hrllo,$name")
}
- fun 函数名(参数列表) = 表达式
fun sum(num1:Int,num2:Int) = num1+num2
3.匿名函数(须赋值给一个变量或常量作为值,否则报错):fun(参数列表)……
val sum = fun(num1:Int,num2:Int){
return num1+num2
}
//调用时:
println("${sum(12,5)}")
Lambda表达式
- Lambda表达式就是匿名函数
- 写法:{参数列表->函数体,最后一行是返回值}
val sum = {a:int,b:Int->a+b}
- 类型
1. ()->Unit //无参,返回值为Unit
2. (Int)->Int//传入整型,返回整型
3. (String,(String->String)->Boolean)//传入字符串,Lambda表达式,返回Boolean
-
Lambda表达式的调用
用()进行调用,等价于invoke()
//定义
val sum = {a:Int,b:Int ->a+b}
//调用
sum(2,3)
sum.invoke(2,3)
- Lambda表达式的简化
- 函数参数调用时最后一个Lambda表达式可以移出去
// args.forEach({ element -> println(element) })
args.forEach() { element -> println(element) }
- 函数参数只有一个Lambda,调用时小括号可以省略
args.forEach { element -> println(element) }
- Lambda只有一个参数可以默认为it(其实就是iterate)
args.forEach { println(it) }
- 入参、返回值与形参一致的函数可以用函数引用的方式作为实参传入
args.forEach(::println)
类成员
- 属性:也就是成员变量,类范围内的变量
- 方法:也就是成员函数。类范围内的函数
- 函数和方法的区别:
- 函数强调功能本身,不考虑丛书
- 方法的称呼通常是从类的角度处方
- 叫法不同而已,莫纠结
- 定义方法:写法与普通函数完全一致,只是写在了类里面
class Hello{
fun sayHello(name:String) = println("Hello,$name")
}
- 定义属性:
- 构造方法参数中val/var修饰的都是属性
- 类内部也可以定义属性
class Hello(val aField:int,notAField:Int){ var anotherField:Float = 3f } //其中aField和anotherField都是属性,而notField则不是属性,只是Hello类的构造方法中的一个参数。
- 属性访问控制
属性可以定义getter/setter
val a:int = 0 get() = field var b:Float = 0f set(value){ field = value }
- 属性初始化
- 属性初始化尽量在构造方法中完成
- 无法在构造方法中初始化,尝试降级为局部变量
- var 用latainit延迟初始化,val用lazy
- 可控类型谨慎用null直接初始化
class X calss A{ var b = 0 lateinit var c:String val e:X by lazy{ X() } }
运算符
- +-*、%^?
- 基本运算符
任何类可以定义或者重载负累的基本运算符
通过运算符对应的具名函数来定义
对参数个数做要求,对参数和返回值类型不做要求
不能像Scala一样定义任意运算符
class Complex(var real: Double, var imaginay: Double) { operator fun plus(other: Complex): Complex { return Complex(real + other.real, imaginay + other.imaginay) } operator fun plus(other: Int): Complex { return Complex(real + other, imaginay) } operator fun plus(other: Any): Int { return real.toInt() } operator fun invoke(): Double { return Math.hypot(real, imaginay) } override fun toString(): String { return "$real+${imaginay}i" } } fun main(args: Array
) { val a = Complex(3.0, 4.0)//3.0+4.0i val b = Complex(5.2, 8.9)//5.2+8.9i println(a + b)//8.2+12.9i println(a + 6)//9.0+4.0i println(a + "HelloWorld!")//3 println(a())//5.0 } - 可以采用中缀表达式自己定义运算符,可以去掉“.”或者“()”调用
class Book {
infix fun on(any: Any): Boolean {//中缀表达式
return false
}
}
class Desk
fun main(args: Array) {
if (Book() on Desk()) {//DSL
}
}
分支表达式(重点是表达式哦)
if表达式
1. if..else
```
if(a==b)...else if(a==c)...else...
```
2. 表达式与完备性
```
val x = if(b<0) 0 else b
val x = if(b<0) 0//错误,赋值时,分支必须完备
```
when表达式
1. 加强版switch,支持任意类型
2. 支持纯表达式分支(类似if)
3. 表达式与完备性
循环语句(非表达式)
- for循环
- 基本写法
for(element in element)... //方式一 for (arg in args) { println(arg) } //方式二 for ((index, value) in args.withIndex()) { println("$index -> $value") } //方式三 for (indexValue in args.withIndex()){ println("${indexValue.index} ->${indexValue.value}") }
- 给任意类实现Iterator方法
- while循环
- 古董级语法(C++,java)
- do...while(...)...
- while(...)...
- 跳过和终止循环
- 跳过当前循环用continue
- 终止循环用break
- 多层循环嵌套的终止结合标签使用
Outter@for(...){ Inner@while(i<0){ if(...)break@outter } }
异常捕获(try...catch)
- cache分支匹配异常类型
- 表达式,可以用来赋值
- finally 无论代码是否抛出异常都会执行
- 注意下面的写法
return try{x/y}cache(e:Exception){
0
}finally{...}
//同样会执行finally,先执行finally中的代码,接着返回
具名参数
- 给函数的实参附上形参
fun sum(arg1:Int,arg2:Int) = arg1+arg2
sum(arg1 =1,arg2 = 3)
变长参数(vararg)
- 某个参数可以接受多个值
- 可以不为最后一个参数(java中变长参数只能是作为最后一个参数,Kotlin中因有具名参数,所以可以不为最后一个参数)
- 如果传参时有歧义,需要使用具名参数
fun main(vararg args: String) {
hello(9.0,1,2,3,4,str = "你好啊")
}
fun hello(d: Double, vararg ints: Int, str: String) {
ints.forEach(::print)
println("$str")
}
SpreadOperator
- 只支持展开Array
- 只能用于变长参数列表的实参
- 不能重载
- 不算一般意义上的运算符
fun main(vararg args: String) {
val array = intArrayOf(1, 3, 4, 6, 87)
hello(9.0, *array, str = "你好啊")
}
fun hello(d: Double, vararg ints: Int, str: String) {
ints.forEach(::print)
println("$str")
}
默认参数
- 为函数参数指定默认值
- 可以为任意位置的参数指定默认值
- 传参时,如果有歧义,需要使用具名参数
fun hello(d: Double = 9.8, vararg ints: Int, str: String) {
println("$d")
ints.forEach(::println)
println("$str")
}
//调用时:
hello(ints = *array, str = "你好啊")