程序结构
常量
- val= value, 值类型
- 类似Java 的final
- 不可能重复复制;
- 举例:
运行时常量: val x=getX()
编译期常量(Java中的静态常量 final): const val x=2
变量
- var = variable
- 举例:
var x =“HelloWorld” //定义变量
x= “HiWorld” // 再次赋值 - 类型推导- 编译器可以推导量的类型
val String =“Hello” // 推导出String类型
val int =5 // Int类型
var x =getString() + 5 // String类型 - var是可变量,val 是不可变,它是常量;val虽然是不可变,但是它不是静态的,如果需要在编译期时就加在,可以在前面加一个const字段;
函数
-
以特定功能组织起来的代码块
fun函数名:[返回值类型]{[函数体]}
fun函数名=[表达式] -
Main函数:
fun main(args: Array<String>){
println("Hello,world")
// 打印args数组的索引为1 的值
println(${args[0]})
if (args.size !=2){
}
}
如果没有传参,会报数组索引异常。这里main函数没有为args赋值;如果启动时,传入了参数就可以打印了;同时如果有返回值,则需要在main(…)这个括号后面加 :返回值类型来定义返回值类型;
· 代码示例:
fun main(args: Array<String>){
checkArgs(args)
val arg1=args[0].toInt()
val arg2=args[1].toInt()
println("$arg1+$arg2=${sum(arg1,arg2)}")
}
fun checkArgs(args: Array<String>){
if(args.size != 2){
println("请传入两个整形参数,例如 1, 2")
System.exit(-1)
}
}
fun sum(arg1: Int ,arg2:Int):Int{
return arg1+arg2
}
函数声明使用fun保留字
fun function() {
println("hello world")
}
如果你需要一个有参数的函数:
fun functionWithParams(x: Any?) {
println("您已将对象传递给此函数: $x")
}
如果你需要一个返回值的话:
fun functionWithReturnValue(): Int {
return Random().nextInt()
}
如果一个函数不返回东西,你可以不写返回值。也可以让它显示返回Unit:
fun functionReturnsUnit(): Unit {
}
如果一个函数不会返回(也就是说只要调用这个函数,那么在它返回之前程序肯定GG了(比如一定会抛出异常的函数)), 因此你也不知道返回值该写啥,那么你可以让它返回Nothing:
fun functionReturnsNothing(): Nothing {
throw RuntimeException("")
}
一个函数也可以拥有Java风格的泛型参数:
fun <T> functionWithGenericsParam(t: T): T {
return t
}
函数参数可以有默认值(关于这个函数中for循环的中缀语法下文会提到,这里可以先忽略):
fun functionWithDefaultParams(limit: Int = 10): Int {
for (i in 0..limit step 2) println(i)
return limit
}
方法
方法和函数几乎一模一样,唯一的区别就是方法必须声明在类里面。下面是一个方法和一个函数:
fun thisIsAFunction() = Unit
class ThisIsAClass {
fun thisIsAMethod() = Unit
}
Lambda表达式
- 匿名函数
- 写法
{[参数列表]->[函数体,最后一行是返回值]}
举例:
val sum ={a:Int,b:Int-> a+b}
- Lambda的类型表示举例:
// 无参,返回值为Unit
()->Unit
// 传入整型,返回一个整型
(Int)->Int
// 传入字符串、Lambda表达式,返回Boolean
(String,(String)->String)->Boolean
- Lambda表达式的调用
用()进行调用
等价于invoke()
举例
val sum ={a:Int,b:Int->a+b}
sum(2,3)
sum.invoke(2,3)
- Lambda表达式的简化
- 函数参数调用时最后一个Lambda可以移出去
- 函数参数只有一个Lambda,调用时小括号可省略
- Lambda只有一个参数可默认为it
- 入参,返回值与形参一致的函数可以用函数引用的方式作为实参传入;
- 使用for 我们用foreach也可以进行遍历;
表达式
- if 表达式
if(判断){
}
else{
}
- When 表达式
- 加强版Switch,支持任意类型
- 支持纯表达式条件分支(类似if)
- 表达式与完备性
- 举例:
fun main(args: Array<String>){
val x=5
when(x){
is Int-> 逻辑代码...
in 1..100-> 逻辑代码...
!in 1..100-> 逻辑代码...
args[0].toInt()-> 逻辑代码...
}
}
这里的when处传入值,下面任意满足条件且按先后只执行第一个符合条件的代码逻辑;
同时还有when不带括号的方式:
var str="今天是周末;"
val biaodian = when {
str.contains("1") -> {
println(1)
}
str.contains("今") -> {
println(2)
}
str.contains(",") -> {
println(3)
}
else -> {
","
}
}
var str="今天是周末;"
val biaodian = if (str.contains(";")){
";"
}else if (str.contains(";")){
";"
}else if (str.contains(",")){
","
}else{
","
}
循环
- for循环
基本写法
for(element in elements)...
While循环
fun main(args:Array<String>){
var x=5
while(x>0){
println(x)
x--
}
do {
println(x)
x--
}while(x>0)
}
- 跳过和终止循环
1.跳过当前循环用continue
终止循环用break
多层循环嵌套的终止结合标签使用
捕获异常
- catch 分支匹配异常类型
- 表达式,可以用来赋值
- finally: 无论代码是否抛出异常都会执行
- 注意下面的写法:
return try(
x/y
)catch(e:Exception){
0
}finally{
...
}
异常的捕获及处理与java类似,不过其可以作为值进行使用;
各种类型参数
- 具名参数
给函数的实参附上形参
fun sum(arg1:Int, arg2:Int){
arg1+arg2
}
sum (arg1=2 ,arg2=3)
- 变长参数
某个参数可以接收多个值
可以不为最后一个参数
如果传参时有歧义,需要使用具名参数 - Spread Operator
只支持展开Array
只用于变长参数列表的实参
不能重载 - 默认参数:
为函数参数指定默认值
可以为任意位置的参数指定默认值
传参时,如果有歧义,需要使用具名参数 - 代码示例:
fun main(vararg args: String){
var array= intArrayOf(1,3,4,5)
// string="Hello" 是一个默认参数
// *array表示将array数组展开,将一个个元素传入,如: hello(3.0,1,3,4,5,string="Hello")
hello(3.0,*array,string="Hello")
}
fun hello(double:Double, vararg ints:Int, string:String){
ints.forEach(::println)
println(string)
}