上一期我们讲到了定义变量的方式,val定义,然后是变量名,类型是放在后面的,使用:隔开:
var name:String = "Tony"
const val pwd_db = "123456"
var是可以变的,val是不可以变的,const就是编译时常量,kotlin还有一个推断机制,可以通过等号后面的内容来推断出这个变量的类型,所以我们可以看到第二条语句是没有指明它的数据类型的;注意,kotlin里面的数据类型首字母大写,而且每条语句的后面是不需要加分号的;
那么这一期我们来讲解一下函数,这是每一门编程语言里面都有的,实现我们功能的代码,以前学习Java的时候我们的函数还记得怎么写的吗?
private static final boolean login(String username, String pwd) {
return Intrinsics.areEqual(username, "Tony") && Intrinsics.areEqual(pwd, "123456");
}
1、先写函数范围,默认就是public,这里我写成private,然后静态,不可变,返回类型,函数名,参数列表和函数体;
再看看kotlin:
//2.5 检验是否是否正确
private fun login(username: String,pwd: String): Boolean{
return if(username == username_db && pwd == pwd_db) true else false
}
同样作用域在前,然后是fun关键字,函数名,参数列表,返回值类型,函数体;
对比一下可以得出一个结论,kotlin是现有输入再有输出的,就是先传的参数,然后就是返回值,但是Java好像是反过来的;
2、这就是一个普通的kotlin函数,当然还有一种叫做匿名函数,没有函数名的函数,通过变量来接收返回值,其实也就是lambda表达式,但是叫做匿名函数好像更好理解:
//1.4 其实匿名函数就是lambda表达式
/*
* 这里的函数含有多个返回类型,所以就设定返回类型为any
* */
val methods4 = {
number:Int->
when(number){
1->"星期一"
2->"星期二"
3->"星期三"
4->"星期四"
else -> -1
}
}
println(methods4(5))
这里是定义一个变量,只有一个变量的名字,让它等于一个大括号,在括号里面我们定义好参数列表,打一个箭头后面就可以当做是函数执行体,最后一行就是返回值,因为程序会推断函数的了返回值类型和变量的类型,所以我们也不需要进行说明,还有这有一种特殊情况,就是函数的返回值类型好像含有多个,于是程序就会将函数的返回类型推断为是any,相当于Java中的object;
3、在kotlin里面有一种函数的高级用法,叫做函数的函数,其实就是在参数列表中传入函数,在C语言中叫做函数指针;
如果Java想要实现的话需要借助接口才可以,而kotlin不需要,这也是一个高级的地方:
//调用登录检测函数,其实这后面的大括号就是lambda表达式参数而已,只是这样写方便;
logincheck("Tony2","123456"){
msg:String,code:Int->
println("最终登录结果:${msg} ${code}")
}
对于传一个函数参数有三种方式,一种就是在小括号里面将这个大括号里面的内容直接写进去,第二种是具名参数,这里用到是第三种,更加方便,也就是直接将要穿的函数写到小括号的后面;
这个函数是:
//2.2 定义一个检测用户名和密码的函数
private fun logincheck(username: String,pwd: String,sponseresult:(String,Int)-> Unit){
//2.3 如果长度不对就报错
if(username == null || pwd == null){
TODO("请输入用户名或密码!")
}
//2.4 合格就验证
if(username.count() > 3 && pwd.count()>3){
if(login(username,pwd)){
sponseresult("登陆成功",200)
}else{
sponseresult("登陆失败",444)
}
}
}
可以看到函数的第三个参数是一个函数;我们在调用函数的时候传入一个函数即可,当然我们可以为这个函数添加内容,这里只是定义了一个函数的形式而已,至于处理的问题我们可以自己在调用的时候写更好;但是函数的参数会被正常的传进来;
4、如果有些小伙伴想要使用中文或者关键字作为函数的名称的话,我们就需要使用反引号来创建函数了,而且引用的时候也是使用反引号:
//这个函数具有一个和关键字冲突的函数名is
public fun `is`(){
println("冲突函数")
}
//使用反引号来调用有冲突的函数
`is`()
当然,如果我们不传入参数和不写返回值类型的话就会被默认为无参且返回值为uit,这个相当于Java的void,只不过前者是类型,是一个类,后者是一个关键字,不能打印和查看;
5、it的使用,这个可以用在函数只有一个参数的时候我们不用申明参数名,直接使用it就可以,因为程序会自动添加上这个参数名;
//1.2 当我们函数只有一个参数时,我们可以不用写参数名,使用it代替即可
val methods2 :(String) -> String ={
it
}
println(methods2("你好"))
对了,这种匿名的函数使用有两种,一种是变量名后面跟=,一种是跟:,有什么区别呢?
:后面必须要声明参数类型和返回值类型,不然会报错,而当好后面就可以不声明参数类型和返回值,所以到这里,我们学习了三种声明和实现函数的方式:
最简单的就是按照作用域,fun,函数名,参数列表,返回值类型,函数体,来写;
其次就是匿名函数里面对冒号(:)后面的,我们需要声明参数类型和返回值类型:
//1.1 匿名函数的声明和实现
val methods1 :(String,Int) -> String = {
n1,n2->
val code = 1
"你的编号为:${code} 用户名: ${n1}年龄 ${n2}"
}
要注意的是参数类型和参数名分开来了,小括号里面的是参数类型,然后一个箭头,后面是返回值类型,再打一个等号后面就可以加大括号成函数执行体;而我们的函数名就在大括号里面的第一行写,并且与函数类型对应即可;
最后一种就是最简洁的等号(=)后面的:
//1.3 使用返回类型推导的函数
val methods3 = {
v1:Int,v2:String->"推导出一个返回类型"
}
println(methods3(78,"Tony"))
我们又使用到了kotlin的类型推导,写出了一个这么简洁的函数,只需要写一个大括号,开头是参数列表,这里就是将参数名和类型像普通的那样写在一起,然后打一个箭头就开始写函数体,最后一条语句就作为函数到返回值,这就是类型推断的强大;
6、最后,我提一点,关于函数的传参, 在kotlin里面也是很强大的:
我们可以给参数设置默认值,那么我们在调用的时候就可以不用传这个有默认值的参数,当然如果传了的话程序就会使用你穿的那个数据:
//1.2 函数的使用
/*
* 可以设置默认值,形式为函数作用范围,fun关键字,函数名,参数列表
* 返回值。记作现有输入,再有输出
* */
private fun methods1(username: String,password: String = "123456"): Int{
println("你的用户名:${username} ,你的密码为${password}")
return 200
}
/*
* 如果含有很多个参数,怕搞错我们还可以通过使用具名参数来做*/
private fun methods2(username: String,password: String = "123456",
username2: String,password2: String = "123456"): Int{
println("你的用户名:${username} ,你的密码为${password};" +
"密保用户为:${username2},密码为:${password2}")
return 200
}
这里有一些函数,但是却有很像的参数,如果数量很多的话就很难传了,那么我们就可以使用后具名参数:
//调用函数
methods1("27833")
//具名参数
methods2(username = "123456", username2 = "7890")
看这里第一个就省略了后面有默认值的参数,第二个就是含有参数名称的传参,是不是很高级?
好了,一起不宜过多,大家快去消化一下,可以试着使用这个函数来改写Java的函数,快去试试吧!