Unit函数的特点
- 类比java中的void 但是java是关键帧,不是类型,很矛盾
- Unit不写,默认也有,Unit代表 无参数返回的忽略类型
package com.fyx.s1
fun main() {
}
fun convert() {
}
fun convert1() : Unit{
}
反引号的作用
- 可以采用汉字或者数字命名函数或者命名一些关键词的函数
package com.fyx.s1
fun main() {
`这是一个中文的函数名称`()
}
fun `这是一个中文的函数名称`() {
}
fun `is`() {
println("ceshi")
}
lambda表达式
- count后面的{} 就是lambda表达式过滤掉不符合条件的值
package com.fyx.s1
fun main() {
var datas = "Jeecg".count {
it == 'e'
}
println(datas)
}
函数变量声明和隐式返回
package com.fyx.s1
fun main() {
var testFuncation: () -> String
testFuncation = {
var count = 100
count.toString()
}
println(testFuncation())
}
函数变量入参声明
package com.fyx.s1
fun main() {
var testfunc: (Int, Int, Int) -> String = { num1, num2, num3 ->
var prifix = "数字集合$num1 +数字 $num2 + 数字 $num3";
prifix
}
println(testfunc(1,2,3))
}
it 的作用和invoke
- it作用于函数只有一个参数时可以使用it使用
- invoke等价与直接使用函数fun1(1,2,3)
package com.fyx.s1
fun main() {
var fun1: (Int, Int, Int) -> String = { n1, n2, n3 ->
var name = "1234"
"这是数字$n1 $n2 $n3 "
}
println(fun1.invoke(1, 2, 3))
var fun2: (String) -> String = {
"这是数字$it "
}
println(fun2.invoke("12"))
}
匿名函数的类型推断
- 方法名 :必须指定返回类型
- 方法名 = 可以根据最后一行得到数据类型自动推断
package com.fyx.s1
fun main() {
var fun1 = {
var name = "1234"
"这是字符串"
}
}
匿名函数lambda表达式和返回类型Any
package com.fyx.s1
fun main() {
var fun1 = { age1: Int, age2: Int ->
"$age1 $age2"
}
println(fun1(12, 12))
var fun2 = { age: Int ->
when (age) {
in 10..20 -> "如花"
else -> -1
}
}
println(fun2.invoke(21))
}
尾随闭包
- 如果函数的最后一个参数是函数类型,如果打算传入一个lambda表达式作为参数,允许在圆括号之外指定Lambda表达式
package com.fyx.s1
fun main() {
var loginResult = { mes: String, code: Int ->
println("登录的结果$mes 状态码$code")
}
login("root", "1234", loginResult)
}
const val USER_NAME = "root"
const val PASS_WORD = "1234"
fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) {
if (username == USER_NAME && Passowrd == PASS_WORD) {
loginResult("登录成功", 200)
} else {
loginResult("登录失败", -200)
}
}
内联
- 如果函数参数有lambda ,尽量使用内联(inline)关键帧,这样内部会做优化,减少函数开辟和对象开辟的损耗
package com.fyx.s1
fun main() {
var loginResult = { mes: String, code: Int ->
println("登录的结果$mes 状态码$code")
}
login("root", "1234", loginResult)
}
const val USER_NAME = "root"
const val PASS_WORD = "1234"
inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) {
if (username == USER_NAME && Passowrd == PASS_WORD) {
loginResult("登录成功", 200)
} else {
loginResult("登录失败", -200)
}
}
内联的注意事项
-
由于JVM对普通函数已经能够根据实际情况智能地判断是否进行内联优化,所以我们并不需要对其使用Kotlin的inline语法,那只会让字节码变得更加复杂。 -
尽量避免对具有大量函数体的函数进行内联,这样会导致过多的字节码数量。 -
一旦一个函数被定义为内联函数,便不能获取闭包类的私有成员,除非你把它们声明为internal。
函数转函数对象
- 这里我们发现直接引用函数报错,因为这是个函数类型的对象,那么如何把函数转化为函数对象呢我们可以使用::
package com.fyx.s1
const val USER_NAME = "root"
const val PASS_WORD = "1234"
fun main() {
login("root", "1234", ::loginResult)
}
fun loginResult(mes: String, code: Int): Unit {
println("登录的结果$mes 状态码$code")
}
inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) {
if (username == USER_NAME && Passowrd == PASS_WORD) {
loginResult("登录成功", 200)
} else {
loginResult("登录失败", -200)
}
}
返回函数参数
package com.fyx.s1
fun main() {
var method2 = method1("详情")
println(method2.invoke("劳烦", 18))
}
fun method1(info: String): (String, Int) -> String {
println(info)
return { name: String, age: Int ->
"$name $age "
}
}
匿名函数和具名函数
package com.fyx.s1
const val USER_NAME = "root"
const val PASS_WORD = "1234"
fun main() {
login("root", "1234", { name, age ->
println("$name + $age ")
})
}
inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) {
if (username == USER_NAME && Passowrd == PASS_WORD) {
loginResult("登录成功", 200)
} else {
loginResult("登录失败", -200)
}
}
package com.fyx.s1
const val USER_NAME = "root"
const val PASS_WORD = "1234"
fun main() {
login("root", "1234",::loginResult)
}
fun loginResult(mes: String, code: Int): Unit {
println("登录的结果$mes 状态码$code")
}
inline fun login(username: String, Passowrd: String, loginResult: (mes: String, code: Int) -> Unit) {
if (username == USER_NAME && Passowrd == PASS_WORD) {
loginResult("登录成功", 200)
} else {
loginResult("登录失败", -200)
}
}
Kotlin的可空特性
- 传统的java项目中能遇到很多空指针异常而在kotlin项目中是不会遇见的
package com.fyx.s1
fun main() {
var name = "test"
name = null
var names: String?
names=null
}
安全调用操作符
- 如果变量被设置为可空,那么针对该变量的所有操作函数都需要进行补救措施,意思就是当为空是就不执行
- 使用方法就是在调用函数时在变量尾部加上?
package com.fyx.s1
fun main() {
var name:String? ="范"
name?.capitalize()
}
let 安全调用
- 当值是空则走入不到let的函数内部,可以对变量进行安全校验
package com.fyx.s1
fun main() {
var name: String? = null
name?.let {
println("不为空")
}
}
!!断言操作
- 意思是如果name空不空都会进行下一步,如果为空进行下一步则包空指针异常
package com.fyx.s1
fun main() {
var name: String? = null
name!!.toBigDecimal();
}
|