IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 学习笔记-Kotlin(2) -> 正文阅读

[移动开发]学习笔记-Kotlin(2)

目录

1.函数内联

2.函数引用

3.函数类型作为返回类型

4.闭包

5.Null

(1)安全调用操作符

(2)非空断言操作符

(3)使用if判断空值

(4)使用空合并操作符

6.异常

1.函数内联

? ? ? ?有关内联的引出,有些材料上说的是:在JVM上,你定义的lambda会以对象实例的形式存在,JVM会为所有同lambda打交道的变量分配内存,这就产生了内存开销,更糟的是,lambda的内存开销会带来严重的性能问题。幸运的是,kotlin有一种优化机制叫内联,有了内联,JVM就不需要使用lambda对象实例了,因而避免了变量内存分配。哪里需要使用lambda,编译器就会将函数体复制粘贴到哪里。
? ? ? ?值得注意的是,使用lambda的递归函数无法内联因为会导致赋值粘贴无限循环,编译会警告。
? ? ? ?内联函数的关键字是inline。例如上次的学习笔记-kotlin(1)中的高阶函数代码咱们来看看它的字节码。操作步骤show kotlin -> Decompile 转换成java咱们更方便看。

fun main(){
    val meilidepaomo:(String, Int) -> String = {goodsName, hour ->
        val currentYear : Int = 2007
        "${currentYear}年, 双11${goodsName}的促销事件剩余${hour}小时"
    }
    showOnBoard("安慕希", meilidepaomo)
}

private fun showOnBoard(goodsName:String, showdowns:(String, Int) -> String) {
    val hour : Int = 6
    println(showdowns(goodsName, hour))
}
public final void main() {
    Function2 meilidepaomo = (Function2)null.INSTANCE;
    this.showOnBoard("安慕希", meilidepaomo);
}

private final void showOnBoard(String goodsName, Function2 showdowns) {
    int hour = 6;
    Object var4 = showdowns.invoke(goodsName, Integer.valueOf(hour));
    boolean var5 = false;
    System.out.println(var4);
}

上边没有使用内联关键字的时候的字节码
下边使用了内联关键字的字节码

fun main(){
    val meilidepaomo:(String, Int) -> String = {goodsName, hour ->
        val currentYear : Int = 2007
        "${currentYear}年, 双11${goodsName}的促销事件剩余${hour}小时"
    }
    showOnBoard("安慕希", meilidepaomo)
}

private inline fun showOnBoard(goodsName:String, showdowns:(String, Int) -> String) {
    val hour : Int = 6
    println(showdowns(goodsName, hour))
}
public final void main() {
   Function2 meilidepaomo = (Function2)null.INSTANCE;
   String goodsName$iv = "安慕希";
   int $i$f$showOnBoard = false;
   int hour$iv = 6;
   Object var6 = meilidepaomo.invoke(goodsName$iv, Integer.valueOf(hour$iv));
   boolean var7 = false;
   System.out.println(var6);
}

private final void showOnBoard(String goodsName, Function2 showdowns) {
   int $i$f$showOnBoard = 0;
   int hour = 6;
   Object var5 = showdowns.invoke(goodsName, Integer.valueOf(hour));
   boolean var6 = false;
   System.out.println(var5);
}

? ? ? ?我们能看出来showOnBoard()函数在加了inline内联关键字后的字节码,把其函数体内的代码赋值粘贴到了main()

2.函数引用

? ? ? ?函数引用方式::函数名
? ? ?
示例:将上边的代码改成具名函数后

fun main(){
    showOnBoard("安慕希", ::meilidepaomo)
}

private fun showOnBoard(goodsName:String, showdowns:(String, Int) -> String) {
    val hour : Int = 6
    println(showdowns(goodsName, hour))
}

private fun meilidepaomo(goodsName:String, hour:Int):String {
    val currentYear : Int = 2007
    return "${currentYear}年, 双11${goodsName}的促销事件剩余${hour}小时"
}

3.函数类型作为返回类型

? ? ? ?函数类型也是返回类型,可以定义一个返回函数的函数。有点绕嘴,哈哈哈。

fun main(){
    val meilidepaomo = showOnBoard();
    println(meilidepaomo("蜡笔小新"))
}

private fun showOnBoard() : (String) -> String {
    val currentYear : Int = 2007;
    val hour : Int = 5;
    return {goodsName:String ->
        "${currentYear}年,双11${goodsName}促销倒计时,剩余${hour}小时"
    }
}

? ? ? ?其中showOnBoard()函数的返回类型是(String)->String的一个函数(一个String的参数,返回值为String),使用meilidepaomo的时候传入一个String参数即可
???????运行结果:2007年,双11蜡笔小新促销倒计时,剩余5小时

4.闭包

? ? ? ?闭包的概念:匿名函数能修改并引用定义在自己的作用域之外的变量,匿名函数引用着定义自身的函数里的变量,kotlin中的lambda就是闭包。换成通俗的讲法就是,function2在funtion1中,function2使用了funtion1中的变量,这个时候我们就称为闭包。
? ? ? ?闭包存在的意义是什么呢?我找到的资料是,kotlin学习脚本语言,脚本语言没有Package的概念,当一个变量在文件A中声明了,在B中用相同的名字声明,就编译警告了。闭包能够保证其作用域。

5.Null

? ? ? ?kotlin区分可空类型和非可空类型。空值异常kotlin会在编译时就警告,而不是等到运行之后再崩溃。除非你接手处理。处理的方式有:

(1)安全调用操作符

? ? ? ?操作符:

val i:Int? = null

? ? ? ?这样我们的Int就是可空类型的了,编辑器再看到安全调用符,如果为空值,就会跳过函数调用,而不是让空值继续执行函数,如:

fun main(){
    val str : String? = getStr()?.plus("222")
    println(str)
}
private fun getStr():String? {
    return "LOVE";
}

运行结果:LOVE222

fun main(){
    val str : String? = getStr()?.plus("222")
    println(str)
}
private fun getStr():String? {
    return null;
}

运行结果:null
? ? ? ?代码不难,getStr()函数返回一个可空的String,?.plus表示不为空的话执行plus方法。第一段代码运行结果LOVE222表示走进了plus()函数,第二段代码运行结果null,表示跳过了函数调用。这样咱们就可以理解之前的一些概念了。

(2)非空断言操作符

? ? ? ?操作符:!!

val str : String? = getStr()!!.plus("222")

? ? ? ?咱们不管是否为空就是要走plus,就可以这样使用,但这样容易空指针异常

(3)使用if判断空值

? ? ? ?这个很好理解了,跟java差不多

if(str == null) {.......}

(4)使用空合并操作符

? ? ? ?操作符:?:

fun main(){
    val str : String? = getStr()?.plus("222")?:"111111"
    println(str)
}
private fun getStr():String? {
    return null;
}

?运行结果:111111
? ? ? ?
如果为空的话,就执行后面的东西。从运行结果上来看,也符合这样的一个逻辑。个人感觉起来更像是3原运算符似的boolean ? 结果1 : 结果2。

6.异常

? ? ? ?抛出异常和java相同

try{
    .....
} catch(e:Exception){
    println(e)
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 12:00:37  更:2022-04-28 12:02:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 23:43:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码