1,具名函数参数
普通形式调用printPlayerStatus函数,传入值参
java
printPlayerStatus(true,20,false)
具名函数参数调用
java
printPlayerStatus(isBlessed = true,healthPoints = 20,isImmortal = false)
如果使用命名值参调用,就可以不用严格按照值参的顺序。
2,Nothing类型
Unit类型的函数没有返回值,Nothing类型的函数也不返回任何东西,但这是他们唯一相同的地方。在编译器看来,Nothing意味着函数不可能成功执行完成,它要么抛异常,要么因其他原因再也不返回调用处。
一般在一个代码我们还没有想好怎么写的时候,但是在后续又必须补全的情况下会使用。,todo函数就是经典的Nothing类型函数。
java
public inline fun TODO(): Nothing = throw NotImplemented Error()
private fun shouldReturnString(): String {
TODO("Implement the string building fuctionality here to return a string")
}
3,函数重载同Java
4,反引号中的函数名
在调用或者定义以空格和其他特殊字符明明的函数时,函数名要用一对反引号括起来。
比如你定义了一个这样的方法
java
private fun '** prolly not a good idea~**'(){
}
调用它
java
'** prolly not a good idea~**'
Kotlin为什么这样子设计呢?原因有2个
1.支持Java互操作,在Kotlin文件中调用Java代码,但是Kotlin和Java各自有不同的保留关键字,不能用于函数名,使用反引号括住函数名就能避免任何潜在冲突。
比如,在Java代码中有一个方法是
java
public static void is(){
}
在Kotlin中,is是保留关键字,那在Kotlin中调用java的is()方法就得使用反引号去调用
java
private fun doSomething(){
//....
//....
'is()'
}
2.通过使用反引号特殊语法,可以在测试文件中使用更加直观易懂的函数名。
5,匿名函数
java
{
val currentYear = 2024
"Welcome to China! (copyright $currentYear )"
}
调用匿名函数
java
println({
val currentYear = 2024
"Welcome to China! (copyright $currentYear )"
})
在花括号的后面跟上一对空的圆括号,表示调用匿名函数。
6,匿名函数的隐式返回
和具名函数不一样,除极少数的情况外,匿名函数不需要return关键字来返回数据。没有return关键字,为了返回数据,匿名函数会隐式或者自动返回番薯体最后一行语句的结果。
7,it关键字
定义只有一个参数的匿名函数时,可以使用it关键字来表示参数名。当你有一个只有一个参数的匿名函数时,it和命名参数都有效。
比如
java
fun main (args Array<String>) {
val greetFuction: (String) ->String = {
playerName ->
val currentYear = 2024
"Welcome to China! (copyright $currentYear )"
}
println(greetFuction("Paul"))
}
使用it关键字可以替换成
java
fun main (args Array<String>) {
val greetFuction: (String) ->String = {
playerName ->
val currentYear = 2024
"Welcome to China! (copyright $currentYear )"
"Welcome $it to China! (copyright $currentYear )"
}
println(greetFuction("Paul"))
}
8,类型推断
定义一个变量时,如果已把匿名函数作为变量赋值给它,就不需要显式指明变量类型了。
之前不带参的匿名函数
java
val greetFuction: () ->String = {
val currentYear = 2024
"Welcome to China! (copyright $currentYear )"
}
使用类型推断
java
val greetFuction = {
val currentYear = 2024
"Welcome to China! (copyright $currentYear )"
}
或者是带参的
java
fun main() {
val greetFuction: (String Int) -> String = { playNmae, numBuildings
val currentYear = 2024
"Welcome to China,$playName! (copyright $currentYear)"
}
}
使用类型推断
java
fun main() {
val greetFuction = { playNmae: String, numBuildings: Int->
val currentYear = 2024
"Welcome to China,$playName! (copyright $currentYear)"
}
}
9,使用函数内联优化lambda引起的内存开销问题,以inline关键字标记使用lambda函数即可。
10,函数引用
::函数名,即可引用函数。
11,null是个特殊值,用来表示var或val变量的值不存在。
null值表示变量不存在,而空字符串表示变量存在,值为""。
String?,问号表示String是一个可空String类型。
null的安全:
选项一.在操作一段无法控制的代码中的变量,无法确定变量是否会返回null时,使用安全调用操作符(?.)
java
fun main(args Array<String>) {
var a = readline()?.capitalize()
println(a)
}
这种情况下,如果readline()返回空,则跳过函数调用,而不是返回null,也就是说当且仅当改变量不为空时,安全调用操作符才能保证针对该变量的函数调用成功执行。
使用let安全调用
java
fun main(args Array<String>) {
var a = readline()?.let{
if(it.isNotBlank()){
it.capitalize()
} else{
"is null"
}
}
println(a)
}
选项二.使用!!.操作符,非空断言操作符
java
fun main(args Array<String>) {
var a = readline()!!.capitalize()
println(a)
}
如果a为null,就会抛出KotlinNullPointerException。
选项三.使用if判断null值情况,使用 != null 做判断条件
使用?:,空合并操作符
这种操作符的意思是,如果我左边的求值结果为null,就使用右边的结果值。
java
fun main(args Array<String>) {
var a = readline()
val b: String = a ?: "bbb"
}
当a为null,则b = "bbb"
12,先决条件
java
var result: String = checkNotNull(a,{"bbb"})
|----------------|-----------------------------------------------------|
| checkNotNull | 如果参数值为null,抛IllegalStateException,否则返回非null值 |
| require | 如果参数值为false,抛IllegalStateException |
| requireNotNull | 如果参数值为null,抛IllegalStateException,否则返回非false值 |
| error | 如果参数值为null,抛IllegalStateException并输出错误信息,否则返回非null值 |
| assert | 如果参数值为false,抛IllegalStateException,并打上断言编译器标记 |
13,@NotNull注解在很多java项目里都能看到,但从Kotlin代码里调用java方法时,它尤其有用,因为Kotlin编译器会使用它决定某个java方法的参数是否可空。