原文地址:https://blog.qjm253.cn/?p=391

魔法预览

  • 实现了Closeable接口的对象可调用use函数
  • use函数会自动关闭调用者(无论中间是否出现异常)
  • Kotlin的File对象和IO流操作变得行云流水

use函数的原型

/*** Executes the given [block] function on this resource and then closes it down correctly whether an exception* is thrown or not.** @param block a function to process this [Closeable] resource.* @return the result of [block] function invoked on this resource.*/
@InlineOnly
@RequireKotlin("1.2", versionKind = RequireKotlinVersionKind.COMPILER_VERSION, message = "Requires newer compiler version to be inlined correctly.")
public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {var exception: Throwable? = nulltry {return block(this)} catch (e: Throwable) {exception = ethrow e} finally {when {apiVersionIsAtLeast(1, 1, 0) -> this.closeFinally(exception)this == null -> {}exception == null -> close()else ->try {close()} catch (closeException: Throwable) {// cause.addSuppressed(closeException) // ignored here}}}
}
  • 可以看出,use函数内部实现也是通过try-catch-finally块捕捉的方式,所以不用担心会有异常抛出导致程序退出
  • close操作在finally里面执行,所以无论是正常结束还是出现异常,都能正确关闭调用者

来一波对比

  • 实现读取一个文件内每一行的功能

    //Java 实现
    FileInputStream fis = null;
    DataInputStream dis = null;
    try {fis = new FileInputStream("/home/test.txt");dis = new DataInputStream(new BufferedInputStream(fis));String lines = "";while((lines = dis.readLine()) != null){System.out.println(lines);}
    } catch (IOException e){e.printStackTrace();
    } finally {try {if(dis != null)dis.close();} catch (IOException e) {e.printStackTrace();}try {if(fis != null)fis.close();} catch (IOException e) {e.printStackTrace();}
    }
    • Kotlin实现

      File("/home/test.txt").readLines().forEach { println(it) }
    • 对Kotlin就是可以两行实现。

    • 仔细翻阅readLines这个扩展函数的实现你会发现,它也是间接调用了use,这样就省去了捕捉异常和关闭的烦恼
    • 同样的,经过包装以后你只需要关注读出来的数据本身而不需要care各种异常情况
  • File的一些其它有用的扩展函数

    /**
    * 将文件里的所有数据以字节数组的形式读出
    * Tip:显然这不适用于大文件,文件过大,会导致创建一个超大数组
    */
    public fun File.readBytes(): ByteArray/**
    * 与上一个函数类似,不过这个是写(如果文件存在,则覆盖)
    */
    public fun File.writeBytes(array: ByteArray): Unit/**
    * 将array数组中的数据添加到文件里(如果文件存在则在文件尾部添加)
    */
    public fun File.appendBytes(array: ByteArray): Unit/**
    * 将文件以指定buffer大小,分块读出(适用于大文件,也是最常用的方法)
    */
    public fun File.forEachBlock(action: (buffer: ByteArray, bytesRead: Int) -> Unit): Unit/**
    * Gets the entire content of this file as a String using UTF-8 or specified [charset].
    *
    * This method is not recommended on huge files. It has an internal limitation of 2 GB file size.
    *
    * @param charset character set to use.
    * @return the entire content of this file as a String.
    */
    public fun File.readText(charset: Charset = Charsets.UTF_8): String/**
    * Sets the content of this file as [text] encoded using UTF-8 or specified [charset].
    * If this file exists, it becomes overwritten.
    *
    * @param text text to write into file.
    * @param charset character set to use.
    */
    public fun File.writeText(text: String, charset: Charset = Charsets.UTF_8): Unit/**
    * Appends [text] to the content of this file using UTF-8 or the specified [charset].
    *
    * @param text text to append to file.
    * @param charset character set to use.
    */
    public fun File.appendText(text: String, charset: Charset = Charsets.UTF_8): Unit/**
    * Reads this file line by line using the specified [charset] and calls [action] for each line.
    * Default charset is UTF-8.
    *
    * You may use this function on huge files.
    *
    * @param charset character set to use.
    * @param action function to process file lines.
    */
    public fun File.forEachLine(charset: Charset = Charsets.UTF_8, action: (line: String) -> Unit): Unit/**
    * Reads the file content as a list of lines.
    *
    * Do not use this function for huge files.
    *
    * @param charset character set to use. By default uses UTF-8 charset.
    * @return list of file lines.
    */
    public fun File.readLines(charset: Charset = Charsets.UTF_8): List<String>/**
    * Calls the [block] callback giving it a sequence of all the lines in this file and closes the reader once
    * the processing is complete.* @param charset character set to use. By default uses UTF-8 charset.
    * @return the value returned by [block].
    */
    @RequireKotlin("1.2", versionKind = RequireKotlinVersionKind.COMPILER_VERSION, message = "Requires newer compiler version to be inlined correctly.")
    public inline fun <T> File.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence<String>) -> T): T
    • 上面的函数都是基于use实现的,可以放心使用,而不用担心异常的发生,并且会自动关闭IO流

Kotlin use函数的魔法相关推荐

  1. 学习Kotlin(五)函数与Lambda表达式

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  2. Kotlin之函数作为参数传递

    1 .Kotlin之函数作为参数传递 我们在写BaseQuickAdapter适配器的时候,有时候嵌套多个BaseQuickAdapter,如果最里面的view触发点击事件,我们可以把函数作为参数通过 ...

  3. Android kotlin run函数学习

    继续来看一下kotlin中run函数的应用,首先看一下源码: /*** Calls the specified function [block] and returns its result.** F ...

  4. kotlin 回调函数、let、also、run 、with、apply 使用总结

    kotlin lambda 简化 --------kotlin 回调函数.let.also.run .with.apply 使用总结 Lambda 表达式(lambda expression)是一个匿 ...

  5. Kotlin学习篇(2)—— Kotlin的函数

    目录 1. 定义一个函数 2. 表达式函数体 3. 更简洁的使用函数 3.1 命名参数 3.2 默认参数值 4. 顶层函数 5. 扩展函数 6. 可变参数 7. 展开运算符 8. 集合相关的函数 9. ...

  6. 二、kotlin的函数

    函数★ 自定义一个打印集合的方法 fun <T> joinToString(collection: Collection<T>,separator: String,prefix ...

  7. 什么?有人整理了Kotlin 集合函数锦集!!

    自从Kotlin官宣为Android开发首选语言后,大家也都正计划很快转向Kotlin或者已经完全转向Kotlin,接下来我们直奔主题了. 我们在Android应用程序中研发过程中,对于 lists, ...

  8. Kotlin 集合函数锦集

    自从Kotlin官宣为Android开发首选语言后,大家也都正计划很快转向Kotlin或者已经完全转向Kotlin,接下来我们直奔主题了. 我们在Android应用程序中研发过程中,对于 lists, ...

  9. python神秘的魔法函数_Python魔法函数

    1.什么是魔法函数 魔法函数即Python类中以__(双下划线)开头,以__(双下划线)结尾的函数,Python提供的函数,可让咱们随意定义类的特性 示例: class Company(object) ...

最新文章

  1. Nat. Commun. | 识别药物靶点的贝叶斯机器学习方法
  2. 看完让你彻底搞懂Websocket原理
  3. 鸟哥的Linux私房菜(基础篇)- 第十七章、程序管理与 SELinux 初探
  4. 【caffe-Windows】cifar实例编译之model的使用
  5. 前端wxml取后台js变量值_这些鲜为人知的前端冷知识,你都GET了吗?
  6. [vue] vue在created和mounted这两个生命周期中请求数据有什么区别呢?
  7. 一次看过瘾的可视化大屏,网友直呼:真酷炫!比Excel强
  8. 为什么要在MD5加密的密码中加“盐”
  9. 洛谷 P5708 【深基2.习2】三角形面积(C)
  10. 郑明秋什么版本的MySQL_mysql数据库实用教程教学课件作者郑明秋代码数据库脚本代码9787568250825.docx...
  11. 堆溢出-unlink
  12. python好学么零基础_python编程好学吗 自学行吗
  13. 快速理解Raft之日志复制(肝了两千五百字)
  14. 【深度学习模型】讲讲横扫nlp任务的BERT模型
  15. 别被忽悠了,程序员告诉你个人所得税年度汇算那些事
  16. 关于numpy中的一维行向量、列向量的理解
  17. 由于和IBM合作“IBM软件人才联盟”的项目,在社区开一个“IBM人才论坛”
  18. 用Fabric构建应收账款融资系统的方法
  19. Java 第四周学习周报
  20. 聚享乐城提醒您:吃水蜜桃 关注奥运会

热门文章

  1. 性能提升30倍丨基于 DolphinDB 的 mytt 指标库实现
  2. 寂静岭2java攻略_寂静岭2攻略 全剧情流程图文攻略+隐藏要素解谜
  3. C++语言程序设计第五版 - 郑莉(第六章课后习题)
  4. 小程序短视频项目———视频展示页面开发
  5. Redis之Redis基础、环境搭建、主从切换
  6. 基于JAVAHTML5运河古城网站计算机毕业设计源码+数据库+lw文档+系统+部署
  7. [踩坑]packets.go:428: busy buffer invalid connection
  8. js 字符串截取 slice 的小bug 以及处理方式
  9. Java -- SQL注入
  10. 教你30元自制考勤打卡系统!