kotlin函数随笔
单句表达式 可以直接 用 = 省略 大括号// 比较常规易懂的 写法fun(a :Int , b : Int):Int{return a + b}// 单句表达式 可以直接 用 = 省略 大括号fun(a :Int , b : Int):Int = a + b// 智能类型fun(a :Int , b : Int) = a + b::双冒号作用fun main(args: Array<Str
单句表达式 可以直接 用 = 省略 大括号
// 比较常规易懂的 写法
fun (a :Int , b : Int):Int{
return a + b
}
// 单句表达式 可以直接 用 = 省略 大括号
fun (a :Int , b : Int):Int = a + b
// 智能类型
fun (a :Int , b : Int) = a + b
::双冒号作用
fun main(args: Array<String>) {
println(testFun("hello", "world!", ::getResult))
}
fun getResult(str1: String, str2: String): String = "result is {$str1 , $str2}"
fun testFun(p1: String, p2: String, method: (str1: String, str2: String) -> String): String {
return method(p1, p2)
}
python里面也可以使用同样的方法,但是没有这么麻烦,因为python的一切皆对象,并不需要这么显示得申明某个参数是函数还是变量。
泛型函数
泛型就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
class Box<T>(t: T) {
var value = t
}
使用时传入具体类型即可
val box: Box<Int> = Box<Int>(1)
python没有指定类型,所以这些也是在Python里面爽多了,看着什么T,感觉眼花
let函数
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
标准用法
let函数在如下2种情况下使用
- 最常用的场景就是使用let函数处理需要针对一个
可null的对象统一做判空处理。 - 然后就是需要去明确一个变量所处特定的作用域范围内可以使用
//表示object不为null的条件下,才会去执行let函数体
object?.let{
it.todo()
...
}
//在函数体内使用it替代object对象去访问其公有的属性和方法
object.let{
it.todo()
...
}
with函数
它是将某对象作为函数的参数,在函数块内可以通过 this 指代该对象,可以在函数体内直接使用对象属性和方法。返回值为函数块的最后一行或指定return表达式。
函数体内部使用this代表对象,而不是it
没有做判空操作,需要手动判空。
run
run函数使用的一般结构
object.run{
//todo
}
//判空
object?.run{
//todo
}
返回值为函数块的最后一行或指定return表达式。
apply
object.run{
//todo
}
//判空
object?.run{
//todo
}
看apply函数和run函数很像,唯一不同点就是它们各自返回的值不一样,run函数是以闭包形式返回最后一行代码的值,而apply函数的返回的是传入对象的本身。
| 函数名 | 定义inline的结构 | 函数体内使用的对象 | 返回值 | 是否是扩展函数 | 适用的场景 |
|---|---|---|---|---|---|
| let | fun T.let(block: (T) -> R): R = block(this) | it指代当前对象 | 闭包形式返回 | 是 | 适用于处理不为null的操作场景 |
| with | fun with(receiver: T, block: T.() -> R): R = receiver.block() | this指代当前对象或者省略 | 闭包形式返回 | 否 | 适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可,经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上 |
| run | fun T.run(block: T.() -> R): R = block() | this指代当前对象或者省略 | 闭包形式返回 | 是 | 适用于let,with函数任何场景。 |
| apply | fun T.apply(block: T.() -> Unit): T { block(); return this } | this指代当前对象或者省略 | 返回this | 是 | 1、适用于run函数的任何场景,一般用于初始化一个对象实例的时候,操作对象属性,并最终返回这个对象。2、动态inflate出一个XML的View的时候需要给View绑定数据也会用到.3、一般可用于多个扩展函数链式调用 4、数据model多层级包裹判空处理的问题 |
->符号
- 分隔 lambda 表达式的参数与主体
- 分隔在函数类型中的参数类型与返回类型声明
- 分隔 when 表达式分支的条件与代码体
$符号
$ 表示一个变量名或者变量值
$ varName 表示变量值
${varName.fun()} 表示变量的方法返回值
${undefinedobject.name} 表示对象属性返回值
?符号
赋值和返回值
//在变量类型后面加上问号,代表该变量是可赋值为null,否则不能赋值为null
var name: String? = "zhangsan"
//方法的返回类型后加上问号,代表方法可以返回null
fun parseInt(str: String): Int? {
// (代码略)
}
//b为非空,则返回b.length ,否则返回 null
b?.length
//安全类型转换as? 如果想安全地进行类型转换, 当转换失败时结果 null, 这种情况可用 as?
val location: Any = "London"
val safeString: String? = location as? String
val safeInt: Int? = location as? Int
// !!符号 这会返回一个非空的 b 值 或者如果 b 为空,就会抛出一个 NPE 异常。它与?.的区别是,!!为空为抛异常,而?.为空,不做处理返回null。
val l = b!!.length
..符号
..配合in和!in一起使用,表示区间的意思.
for(i in 1..10) { // 等同于 1 <= i && i <= 10
println(i)
}
//使用until函数,创建一个不包括其结束元素的区间
for (i in 1 until 10) { // i in [1, 10) 排除了 10
println(i)
}
// 使用 step 指定步长
for (i in 1..4 step 2) {
print(i) // 输出“13”
}
//由大到小,使用downTo
for (i in 4 downTo 1 step 2){
print(i) // 输出“42”
}
@符号
在kotlin标签语法中使用。
在 Kotlin 中任何表达式都可以用标签(label)来标记。 标签的格式为标识符后跟 @ 符号,例如:abc@
标签语法经常和break和return使用,用于指定从标签处中断或从标签处返回。
{}符号
{}符号中定义lambda表达式
*符号
扩展符号,可以用于拼接数组
val a = arrayOf(1, 2, 3)
var b = arrayOf(*a, 2)
val list = asList(-1, 0, *a, 4)
//或者
val c = intArrayOf(1,2,3)
val d = intArrayOf(*c, 4,5)
Lambda表达式和匿名函数
fun compare(a: Int, b: Int): Int{
return a +b
}
add(::compare)
更多推荐



所有评论(0)