单句表达式 可以直接 用 = 省略 大括号

// 比较常规易懂的 写法
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多层级包裹判空处理的问题

->符号

$符号

$ 表示一个变量名或者变量值
$ 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)
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐