1、常量与变量(var,val)
var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量。这种声明变量的方式和java中声明变量的方式一样。
val是一个只读变量,这种声明变量的方式相当于java中的final变量。一个val创建的时候必须初始化,因为以后不能被改变。
什么是常量?
val = value,值类型
类似Java的final
不能重复赋值
举例:
运行时常量:val x = getX()
编译期常量:const val x = 2 会提高执行效率
什么是变量?
var = variable
举例:
var x = "HelloWorld"//定义变量
x = "HiWorld"//再次赋值
类型推导
编译器可以推导量的类型
val string = "Hello" //推导出String类型
val int = 5 //Int类型
val x = getString() + 5//String类型
2、函数(function)
什么是函数?
以特定功能组织起来的代码块
fun函数名:[返回值类型]{[函数体]}
fun函数名 = [表达式] //返回值是Unit(相当于java中的void),可不写
匿名函数
fun([参数列表])...
举例:
val say = fun(name:String) = println("Hello")
3、lambda表达式
实际上就是匿名函数
写法{[参数列表]->[函数体,最后一行是返回值]}
举例:
val sum = {a:Int,b:Int->a+b}
返回的是a+b的和
类型表示举例
1、()->Unit无参,返回值为Unit
2、(Int)->Int传入整型,返回一个整型
3、(String,(String)->String)->Boolean传入字符串、Lambda表达式,返回Boolan
Lambda表达式的调用
1、用()进行调用
2、等价于invoke()
举例
val sum = {a:Int,b:Int->a+b}
sum(2,3)
sum.invoke(2,3)
Lambda表达式的简化
1、如果函数调用时,最后一个是lambda表达式,在传参的时候可以将它移出去
2、函数参数只有一个lambda表达式,调用时小括号可省略
3、lambda表达式只有一个参数,不写也可以,名字默认为it
4、实参、返回值与形参一致的函数可以用方式作为实参传入
4、类成员(成员方法、成员变量)
属性
或者说成员变量,类范围内的变量
方法
或者说成员函数,类范围内的函数
函数和方法的区别
1、函数强调功能本身,不考虑从属
2、方法的称呼通常是丛类的角度出发
3、叫法不同
定义方法
写法与普通函数完全一致
定义属性
1、构造方法参数中var/val修饰的都是属性
2、类内部也可以定义属性
class Hello(val aField:Int,notAFlield:Int){
var anotherField:Float = 3f
}
aField 是属性
notAField 不是属性,只是普通构造方法的参数
属性的访问控制
属性可以定义getter/setter
举例:
var a: Int = 0
get() = field
set(value) {
field = value
}
val b:Float = 0f
//set(value){ field =value}
get() = field
属性初始化
1、属性的初始化尽量在构造方法中完成
2、无法在构造方法中初始化,尝试降级为局部变量
3、var用lateinit延迟初始化,val用lazy
4、可空类型谨慎用null直接初始化(不建议使用null初始化)
class LazyTest {
var a: Int = 0;
lateinit var str: String
lateinit var x1: X
val STR: String = "STR"
val x2: X by lazy {
print("lazy X")
X()
}
}
class X
fun main(args: Array
val e: LazyTest = LazyTest()
e.x2
}
5、基本运算符
1、任何类都可以定义或重载父类的基本运算符
2、通过运算符对应的具名函数来定义
3、对参数的个数要求,对参数和返回值类型不做要求
4、不能像Scala一样定义任意运算符
6、表达式(中缀表达式、分支表达式、when表达式等)
1、中缀表达式
只有一个参数,且用infix修饰的函数
fun main(args: Array) {
val b = Book();
b on "哈哈"
}
class Book {
infix fun on(str: String) {
print("Book on $str")
}
}
运行结果:Book on 哈哈
2、分支表达式
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 //错误,赋值时,分支必须完备
3、when表达式
1)加强版switch,支持任意类型,不需些break
2)支持纯表达式条件分支(类似if)
3)表达式与完备性
举例:
fun main(args: Array) {
val x = 5
when (x) {
is Int -> println("整型")
in 0..10 -> println(" x in 0..10")
in 0..100 -> println(" x in 0..100")
5 -> println("x:$x 值是5")
}
val a = when{
x in 0..10 ->100
else ->0
}
print("a的值是$a")
}
结果:
7、循环语句(for循环、while循环、continue、break)
1)for循环
a.基本写法
for(element in elements)...
b.给任意类实现Iterator方法
运行机制简单举例:
class MyIterator(val iterator:Iterator){
operator fun next():Int{
return iterator.next()
}
operator fun hasNext():Boolean{
return iterator.hasNext()
}
}
class MyIntList{
private val list = ArrayList()
fun add(int:Int){
list.add(int)
}
fun remove(int:Int){
list.remove(int)
}
operator fun iterator():MyIterator{
return MyIterator(list.iterator())
}
}
fun main(args: Array) {
val list = MyIntList()
list.add(1)
list.add(2)
list.add(3)
for (i in list){
println(i)
}
}
2)while循环
a. do...while(...)...
b. while(...)...
3)continue
跳过当前循环
4)break
终止循环
多层循环嵌套的终止结合标签使用
Outter@for(...){
Inner@while(i<0){if(...break@Outter)}
}
如果break后面没有@Outter,是把while给break了,会继续执行for循环,如果加了@Outter了,就是for循环给break了
8、异常捕获(try...catch、finally)
try...catch
1、catch分支匹配异常类型
2、表达式,可以用来赋值,与if..else、when类似
例如:
fun main(args: Array) {
val a = try {
0 / 3
} catch (e: Exception) {
e.printStackTrace()
println("出现异常")
0
} finally {
println("执行finally")
}
println(a)
}
运行结果:
执行finally
3
finally
无论代码是否抛出异常都会执行
return try(x/y)catch(e:Exception){0}finally{...}
如果抛异常返回0,否则返回x/y,finally一定会执行,先执行finally再返回。
9、具名参数,变长参数、默认参数
1)具名参数
给函数的实参附上形参
举例:
fun sum(arg1:Int,arg2:Int) = arg1+arg2
sum(arg1=2,arg2=3)
2)变长参数
a.某个参数可以接收多个值
b.可以不为最后一个参数
c.如果传参时有歧义,需要使用具名参数
Spread Opreator
a.只支持展开的Array
b.只用于变长参数列表的实参
c.不能重载
3)默认参数
a.为函数参数指定默认值
b.可以为任意位置的参数指定默认值
c.传参时,如果有歧义,需要使用具名参数
10.练习
1)简单实现计算器
fun main(args: Array) {
while (ok()) {
try {
println("请输入,例如:3 + 4")
val input = readLine() ?: break
val split = input.trim().split(" ")
if (split.size < 3) {
throw IllegalArgumentException("参数个数不对")
}
val a = split[0].toDouble()
val op = split[1]
val b = split[2].toDouble()
println("$a $op $b -> ${Opreator(op).apply(a, b)}")
} catch (e: NumberFormatException) {
println("您输入的数字有误")
} catch (e:IllegalArgumentException) {
println("参数有误")
}catch (e:Exception){
println("其他异常,${e.message}")
}
println("再来一发吗?[Y]")
val cmd = readLine()
if (cmd == null || cmd.toLowerCase() != "y") {
break
}
}
println("退出成功!")
}
fun ok(): Boolean {
return true
}