kotlin 中函数用fun来声明
fun onCreate(){
}
如果函数是继承的父类的话 需要用的override关键字override fun onCreate(){ }
(反正重写的时候会自动加上,这里也不必过多的记忆区分,如果函数可以被继承则需要 open override fun onCreate(){ }
)
如果函数是有入参的话 fun onCreate(str: String) { }
kotlin的函数返回值在 ()
之后以: 返回值类型
的形式声明
无返回值情况下:
Unit是个空类型,类似于void,不过在kotlin中,如果函
数没有返回值,则可以不用声明 这一点跟java不同,当然也可以声明为Unit
fun person(){
}
fun person(): Unit{
}
这两个方法是相同的
有返回值的情况下:
直接return返回即可
fun person(): String{
return "str"
}
函数的命名
fun person(name: String,age: Int = 0,job: String = "xxx",isMan: Boolean = false): Unit{
println("name:$name age: $age job:$job isMan:$isMan")
}
我们声明一个描述person的函数,其中age,job和isMan都有默认值
正常情况下我们调用方式是(函数所在的类是KtolinTest):
mKtolinTest.person("chuan",1,"android",true)
因为我们在声明函数的时候 部分参数有了默认值,如果我们要使用默认值得话再调用函数的时候可以不用再次传值
mKotlinTest.person("chuan")
输出为I/System.out: name:chuan age: 0 job:xxx isMan:false
其次我们在调用函数的时候 可以通过属性名:属性值的方式来作为函数的入参,提高可读性,而且使用这种方式的话,可以不用依赖函数的入参顺序
kotlinTest.person(name = "chuan",isMan = true,job = "android")
输出为 name:chuan age: 0 job:android isMan:true
注意:使用命名参数时,所有位置参数都要放在命名参数之前,例如:
kotlinTest.person("chuan",isMan = true)
而kotlinTest.person(isMan = true,"chuan")
这样是不可以的,即:命名参数位于最后位置
局部函数
平常我们用到的函数都是成员函数,成员一词也是与成员变量相对的,反正本人没有接触过,不过局部变量倒是接触比较多 /手动滑稽,在ktolin中就有了相应的局部函数
,即函数内部的函数
fun person(name: String,age: Int = 0,job: String = "xxx",isMan: Boolean = false){
var mName: String = name
fun job(a: Int): String{
return "name:$name a:$a"
}
var str: String = job(age)
println("name:$name age: $age job:$job isMan:$isMan")
}
按照官方的来说就是声明一个局部作用域,仅供父函数调用,如果其他的成员函数也可以调用的话,则可以声明一个成员函数,局部函数中可以调用父函数的局部变量
以往我们可能在写一个功能的时候,会使一个函数的代码量变的很大,然后我们会抽出部分函数作为成员函数,供当前函数调用,抽出来的函数如果有其他的成员函数引用还好,如果只是仅有一个函数调用的话 可读性会降低很多,如果一个函数调用另一个函数再调用另一个函数的话,这种深层次的调用,会使人很抓狂,因为当前函数看完了,上一个函数的作用可能忘记了,也有可能参数的意义忘记了等等,局部函数还是值得一试的
可变数量的参数
在java中如果是可变数量的参数,直接..即可,但是在kotlin中 则需要使用vararg关键字来声明
fun foo(vararg ts: String,str: String){
}
这算是一个比较特殊的vararg函数,因为你不知道到哪里是ts,到哪里是str
此时我们可以这样使用
kotlinTest.foo("chuan","chuan","chuan","chuan","chuan",str = "chuan")
来避免一些冲突问题
中缀表示法
表示在调用用infix
关键字修饰的函数时,可以忽略调用的点和圆括号
infix fun foo(type: String): Int{
var re: Result = function()
var (resu,sta) = re
println("result:$resu status:$sta")
return 1
}
fun Main(){
this foo "chuan"
}
抛开函数里面的逻辑不看,但看调用,普通调用是this.foo("chuan")
,如果使用中缀表示法调用的话则是this foo "chuan"
中缀函数需要满足的要求:
他们必须是成员函数或者扩展函数
他们必须只有一个参数
其参数不得接收可变数量的参数且不能有默认值
foo
函数内部包含有解构声明 这一部分在kotlin(三)中会提到
data class Result(){}
扩展函数
上面说到了扩展函数,这里就说一下
声明一个扩展函数,我们需要用一个被扩展的类型来作为他的前缀,以KotlinTest类为例
// 声明一个测试类
class KotlinTest{
fun test(){
}
}
// 声明一个调用类
class Mult{
fun Main(){
KotlinTest kotlinTtest = KotlinTest()
// 调用KotlinTest类的扩展方法
kotlinTest.Main()
}
// 为KotlinTest类声明一个扩展方法
fun KotlinTest.Main(){
println("KotlinTest Main ")
}
}
如上所示,最后输出的是/com.chuan.jun I/System.out: KotlinTest Main
注意:KotlinTest.Main()的调用只能在声明类里面调用,如果此时还有一个类Test,即使我们有kotlinTest对象,但也调用不到Main函数
如果我们在KotlinTest类中 声明一个Main函数,那么在Mult中调用Main函数的时候,会调用KotlinTest的Main函数,不会调用扩展函数Main
class KotlinTest{
fun test(){
}
fun Main(){
println("-------KotlinTest Main-------")
}
}
class Mult{
fun Main(){
KotlinTest kotlinTtest = KotlinTest()
// 调用KotlinTest类的扩展方法
kotlinTest.Main()
}
// 为KotlinTest类声明一个扩展方法
fun KotlinTest.Main(){
println("KotlinTest Main ")
}
}
输出为com.chuan.jun I/System.out: -------KotlinTest Main-------
扩展还有一种省略函数名的,不知道这种的是什么意思,有什么注意点,可能跟扩展属性有关,有知道的同学留言下,写法如下
var kk = fun KotlinTest.(age: Int): KotlinTest = this.also { println("kkkk---$age") }
声明一个函数表达式fun KotlinTest(age: Int): KotlinTest = this.also { Main() }
其中this表示KotlinTest本身,也就是fun后面的那个KotlinTesty,
this.also返回KotlinTest类型的对象,后面会单独说,并且调用了KotlinTest的Main方法,我们来调用下
kotlinTest: KotlinTest = KotlinTest()
kotlinTest.kk(1)
输出为:com.chuan.jun I/System.out: kkkk---1
内联扩展函数
- let:let扩展函数的实际上是一个作用域函数,当你需要去定义一个变量在一个特定的作用域范围内,let函数的是一个不错的选择;let函数另一个作用就是可以避免写一些判断null的操作。
object.let{
it.todo()//在函数体内使用it替代object对象去访问其公有的属性和方法
...
}
//另一种用途 判断object为null的操作
object?.let{//表示object不为null的条件下,才会去执行let函数体
it.todo()
}
实例:
var kar: String = kotlinTest.let { // 定义变量kar,变量类型为String
it.person(name = "chuan") // it代表kotlinTest对象 调用kotlinTest的person对象
"chuan2222" // 最后一行为返回值
println(kar)
输出chuan2222
- with
with(object){
//todo
}
实例:
var kar: String = with(kotlinTest){
Main()
"chuan"
}
总的来说跟let的使用差不多
- run
object.run{
//todo
}
run函数实际上可以说是let和with两个函数的结合体,run函数只接收一个lambda函数为参数,以闭包形式返回,返回值为最后一行的值或者指定的return的表达式。
- apply
object.apply{
//todo
}
实例:
var kar = kotlinTest.apply { it.Main() }
kar.Main()
从结构上来看apply函数和run函数很像,唯一不同点就是它们各自返回的值不一样,run函数是以闭包形式返回最后一行代码的值,而apply函数的返回的是传入对象的本身。
- also
object.also{
//todo
}
also函数和let很像,只是唯一的不同点就是let函数最后的返回值是最后一行的返回值而also函数的返回值是返回当前的这个对象。
网友评论