【Android面试八股文】Kotlin内置标准函数with的原理是什么?

2024-06-20 03:28

本文主要是介绍【Android面试八股文】Kotlin内置标准函数with的原理是什么?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 原理和实现方式
  • 应用场景
  • 总结

with 是 Kotlin 标准库中的一个内置函数,其主要目的是简化对某个对象实例执行多个操作的代码。它的原理和实现方式如下:

原理和实现方式

with的源码定义如下:

/*** Calls the specified function [block] with the given [receiver] as its receiver and returns its result.** For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#with).*/
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {contract {callsInPlace(block, InvocationKind.EXACTLY_ONCE)}return receiver.block()
}
  1. 函数签名

    public inline fun <T, R> with(receiver: T, block: T.() -> R): R
    
    • with 函数接受两个参数:
      • receiver:要操作的对象实例,即调用者对象。
      • block:一个函数类型的参数,它是作为 receiver 的扩展函数,可以在 receiver 上调用,返回类型为 R
  2. 内联函数

    • with 函数使用 inline 修饰符声明,这意味着编译器在编译时会将函数调用处的代码直接替换为 with 函数中的代码,以避免函数调用的额外开销。
  3. 作用

    • 当调用 with(receiver) { ... } 时,编译器会将 { ... } 中的代码块视为 receiver 对象的一个扩展函数。因此,在这个代码块中,可以直接访问 receiver 对象的成员函数和属性,无需显式地使用 receiver. 来引用它们。
  4. 执行流程

    • with 函数会将 receiver 对象传递给 block 函数(作为 this 对象),然后在 block 函数中执行相应的操作。
    • block 函数中可以直接调用 receiver 对象的成员函数和属性,而且编译器会自动处理成员函数和属性的访问。
  5. 返回值

    • with 函数的返回值是 block 函数的返回值 R,即执行完 block 中的代码后的返回结果。

应用场景

  • 简化代码:特别适合在对同一个对象实例进行多个操作时,避免重复地使用对象名字来调用其方法或访问属性。
  • 可读性:使代码更加清晰,因为在 with 块中可以直接看到对对象实例的操作,而无需反复引用对象名。
  • 避免误用:减少因多次使用同一个对象实例而可能引入的错误,如对象名拼写错误或多次引用导致的代码混乱。
  1. 操作同一个对象的多个属性或方法

    使用 with 的场景

    val person = Person("Alice", 30)with(person) {println("Name: $name")age += 1
    }
    

    在这个例子中,可以在 with 语句块中直接使用 nameage,而不需要每次都写 person.

    不使用 with 的场景

    val person = Person("Alice", 30)println("Name: ${person.name}")
    person.age += 1
    

    没有使用 with 的情况下,每次操作对象属性或方法时都需要显式地使用对象名字。

    区别

    • 使用 with 可以减少重复代码,提高可读性,特别是在操作同一个对象的多个属性或方法时,可以更为简洁地表达逻辑。
  2. 执行一系列对象的操作

    使用 with 的场景

    val stringBuilder = StringBuilder()with(stringBuilder) {append("Hello, ")append("Kotlin!")
    }
    val result = stringBuilder.toString()
    

    with 允许在代码块中直接对 StringBuilder 实例进行多次操作,避免了重复使用 stringBuilder.

    不使用 with 的场景

    val stringBuilder = StringBuilder()stringBuilder.append("Hello, ")
    stringBuilder.append("Kotlin!")val result = stringBuilder.toString()
    

    在没有使用 with 的情况下,每次操作 StringBuilder 都需要显式地使用 stringBuilder.

    区别

    • 使用 with 可以使代码更为紧凑和可读,特别是在需要对同一个对象进行多次操作时,能够清晰地看到针对对象的连续操作。
  3. 操作函数内的局部变量

    使用 with 的场景

    fun buildString(): String {val stringBuilder = StringBuilder()with(stringBuilder) {append("Hello, ")append("World!")}return stringBuilder.toString()
    }
    

    在函数内部使用 with 可以简化对局部变量的操作,特别是在构建复杂数据结构时很有用。

    不使用 with 的场景

    fun buildString(): String {val stringBuilder = StringBuilder()stringBuilder.append("Hello, ")stringBuilder.append("World!")return stringBuilder.toString()
    }
    

    没有使用 with 的情况下,代码可能显得更加冗长。

    区别

    • 使用 with 可以将代码块的重点放在对象操作上,而不是对象的引用,使得函数的逻辑更加清晰和集中。

总结

使用 with 函数的主要优势在于它可以减少重复的对象名字引用,提高代码的可读性和清晰度。通过将对象作为 block 函数的接收者,在 block 内部可以直接访问对象的成员,从而简化了对同一个对象的多次操作。相比之下,不使用 with 可能导致代码重复引用对象名字,使得代码显得更加冗长和分散。

这篇关于【Android面试八股文】Kotlin内置标准函数with的原理是什么?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076970

相关文章

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如