kotlin精讲-第2章(9)kotlin函数加强_上
Kotlin相比于Java
相比于java | 描述 |
---|---|
新增 | 表达式函可以去掉方法大括号,代码更清爽 |
新增 | 命名参数,提高代码可读写 |
新增 | 默认参数,形参定义带上默认值 |
优化 | 命名参数+默认参数,取代繁琐的重载 |
目标
要求 | 知识点 |
---|---|
掌握 | 如何把函数转换为表达式函数体 |
掌握 | 命名参数和默认参数的配合使用 |
掌握 | 命名参数和默认参数在使用过程中需要注意的事项 |
表达式函数体
转换为表达式函数体
说到函数,还记得我们前面讲过的4种函数类型吧?“函数一共就有4种类型,无参无返回值、无参有返回值、有参无返回值、有参有返回值”。参考代码:

针对上面的4个方法,我们把鼠标放到代码第3行,函数体里面的【println(“myFun1”) 】,然后按alt+Enter快捷键,就会看到如下提示,参考截图:

我们选中“Convert to expression body”,对4个方法进行转换,得到如下结果如下

表达式函数体定义
那什么是表达式函数体呢?现在应该已经很明白了,就是函数体之前放在大括号里面,现在可以放在等号右边。
是不是所有的函数都能用表达式函数体呢?不是。函数体只有一行代码的时候,才能用表达式函数体。上面的4个函数正好都能转换为表达式函数体,不过是碰巧上面4个方法的函数体内容就只有一行。如果方法体不止一行,就没法转换为表达式函数体,参考代码:
【代码清单-达式作为函数体3转换约束.kt】

我们发现,这个时候就没有“Convert toexpression body”提示了。
表达式函数体作用
表达式函数体作用是什么呢?
-
针对函数体只有一行代码的情况,多了一种表达形式。
-
针对函数体只有一行代码的情况,代码显得更加清爽,没有了大括号。
-
表达式函数体支持返回类型自动推断。显得比较智能。
针对第3点优点,参考代码:

上面2个方法都是很编译通过的。
所以,【Kotlin相比于Java,使用表达式函数体,简化函数方法体只有一行代码情况下函数的定义】
命名参数
命令参数是指在方法调用的时候,传入实参的时候,可以按照特定格式传入形参名字。命令参数的第一个作用就是提高代码的可读性。命名参数的使用格式如下:
methodName(形参名字=实参, 形参名字=实参, 形参名字=实参…)
我们看一段代码,先不用命名参数,代码如下:

针对以上的reformat方法,这个方法没有去贴方法体,因为不是重点。我们看reformat方法的参数,包含一个Sring类型,三个boolean类型,一个Char类型。所以,第10行,方法调用的时候,就需要进行如下的方式传递:

但是,这样长期以往就可能存在一个问题,代码的可读性问题。久而久之,只看方法的调用,就会傻傻分不清楚三个boolean实参具体含义了。
但是,如果使用命名参数,代码的可读性就大大提高了。我们看一下使用命名参数之后的代码,代码如下:

如果调用的时候,都这么去写,代码的可读性就大大提高了。所以,【Kotlin相比于Java,命名参数提高了代码的可读性】。这就是命令参数的第一个作用。其实这个作用已经不明显,因为高版本的IDEA即使你不写命名参数,IDEA会自动帮我们显示,提高代码的可读性,参考截图:

命名参数的其他作用,需要和默认参数配合起来。
默认参数
什么是默认参数?就是,我们在函数定义的时候,可以给每一个形参,选择性的给一个默认实参。默认参数定义格式如下:

我们举一个具体的方法定义的例子,代码如下:

那如果一个函数,有默认参数我们可以该怎么调用呢?参考代码:

针对以上代码,得到些什么结论呢?第一,如果方法定义的时候,没有默认参数,方法调用的时候必须传递具体的实参。第二,如果方法带有默认参数,方法调用的时候可以不用传递具体实参,不传递实参的情况下,方法使用默认参数。
我们更进一步,默认参数+命名参数,可以传递指定位置的参数。比如,我们传递参数1、3、5,代码如下:

针对以上代码我们发现,默认参数和命名参数结合起来之后。方法参数多,可以组合出多种调用方法。如果在Java里面,需要重载好多的方法,才能完成多种形式的调用。
所以,【Kotlin相比于Java,通过默认参数加命名参数,减少了方法的重载,写一个方法,可以有多种调用形式】。
关于默认参数和命名参数有如下2个注意的地方。
第一,带默认参数的方法,如果不使用命名参数,只能从头开始赋值。也就是赋值参数1、参数12、参数123、参数1234、参数12345。如果想参数124、参数125之类的是不行的,参考代码:

针对以上代码,我们看到第24行,26行的调用,编译器都当我们传递的第三个参数是参数3,而不是我们想的参数4和参数5。
第二,带默认参数的方法,某一个参数使用了命名参数,后面的参数赋值都需要使用命名参数。参考代码:

针对以上代码,第二个参数使用了命名参数,后面不管想传递参数3还是参数4还是参数5,都需要使用命名才是才能识别了。