public inline fun TODO(): Nothing = throw NotImplementedError()

@kotlin.internal.InlineOnly public inline fun TODO(reason: String): Nothing =  throw NotImplementedError(“An operation is not implemented: $reason”)

举例说明:

fun main(args: Array) { TODO(“测试TODO函数,是否显示抛出错误”) }

输出结果为:

如果调用TODO()时,不传参数的,则会输出An operation is not implemented.

3.2 、run()函数

run函数这里分为两种情况讲解,因为在源码中也分为两个函数来实现的。采用不同的run函数会有不同的效果。

3.2.1、run()

我们看下其源码:

public inline fun  run(block: () -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() }

关于contract这部分代码小生也不是很懂其意思。在一些大牛的blog上说是其编辑器对上下文的推断。但是我也不知道对不对,因为在官网中,对这个东西也没有讲解到。不过这个单词的意思是契约,合同等等意思。我想应该和这个有关。在这里我就不做深究了。主要讲讲run{}函数的用法其含义。

这里我们只关心return block()这行代码。从源码中我们可以看出,run函数仅仅是执行了我们的block(),即一个Lambda表达式,而后返回了执行的结果。

用法1:

当我们需要执行一个代码块的时候就可以用到这个函数,并且这个代码块是独立的。即我可以在run()函数中写一些和项目无关的代码,因为它不会影响项目的正常运行。

例: 在一个函数中使用

private fun testRun1() { val str = “kotlin”

run{ val str = “java”   // 和上面的变量不会冲突 println(“str = $str”) }

println(“str = $str”) }

输出结果:

str = java str = kotlin

用法2:

因为run函数执行了我传进去的lambda表达式并返回了执行的结果,所以当一个业务逻辑都需要执行同一段代码而根据不同的条件去判断得到不同结果的时候。可以用到run函数

例:都要获取字符串的长度。

val index = 3 val num = run { when(index){ 0 -> “kotlin” 1 -> “java” 2 -> “php” 3 -> “javaScript” else -> “none” } }.length println(“num = $num”)

输出结果为:

num = 10

3.2.2、T.run()

其实T.run()函数和run()函数差不多,关于这两者之间的差别我们看看其源码实现就明白了:

public inline fun  T.run(block: T.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() }

从源码中我们可以看出,block()这个函数参数是一个扩展在T类型下的函数。这说明我的block()函数可以可以使用当前对象的上下文。所以当我们传入的lambda表达式想要使用当前对象的上下文的时候,我们可以使用这个函数。

例:

val str = “kotlin” str.run { println( “length = 

t

h

i

s

.

l

e

n

g

t

h

"

 

)

p

r

i

n

t

l

n

(

 

"

f

i

r

s

t

 

=

 

{this.length}" ) println( "first = 

this.length" )println( "first = {first()}”) println( “last = ${last()}” ) }

输出结果为:

length = 6 first = k last = n

在其中,可以使用this关键字,因为在这里它就代码str这个对象,也可以省略。因为在源码中我们就可以看出,block()就是一个T类型的扩展函数。

这在实际的开发当中我们可以这样用:

例: 为TextView设置属性。

val mTvBtn = findViewById(R.id.text) mTvBtn.run{ text = “kotlin” textSize = 13f … }

3.3 、with()函数

其实with()函数和T.run()函数的作用是相同的,我们这里看下其实现源码:

public inline fun  with(receiver: T, block: T.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return receiver.block() }

这两个函数的区别在于:

with是正常的高阶函数,T.run()是扩展的高阶函数。with函数的返回值指定了receiver为接收者。

例:实现上面的T.run()函数的列子

val str = “kotlin” with(str) { println( “length = 

t

h

i

s

.

l

e

n

g

t

h

"

 

)

p

r

i

n

t

l

n

(

 

"

f

i

r

s

t

 

=

 

{this.length}" ) println( "first = 

this.length" )println( "first = {first()}”) println( “last = ${last()}” ) }

输出结果为:

length = 6 first = k last = n

例:当我的对象可为null的时候,看两个函数之间的便利性

val newStr : String? = “kotlin”

with(newStr){ println( “length = 

t

h

i

s

?

.

l

e

n

g

t

h

"

 

)

p

r

i

n

t

l

n

(

 

"

f

i

r

s

t

 

=

 

{this?.length}" ) println( "first = 

this?.length" )println( "first = {this?.first()}”) println( “last = ${this?.last()}” ) }

newStr?.run { println( “length = 

l

e

n

g

t

h

"

 

)

p

r

i

n

t

l

n

(

 

"

f

i

r

s

t

 

=

 

length" ) println( "first = 

length" )println( "first = {first()}”) println( “last = ${last()}” ) }

从上面的代码我们就可以看出,当我们使用对象可为null时,使用T.run()比使用with()函数从代码的可读性与简洁性来说要好一些。当然关于怎样去选择使用这两个函数,就得根据实际的需求以及自己的喜好了。

3.4、T.apply()函数

我们先看下T.apply()函数的源码:

public inline fun  T.apply(block: T.() -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block() return this }

从T.apply()源码中在结合前面提到的T.run()函数的源码我们可以得出,这两个函数的逻辑差不多,唯一的区别是T,apply执行完了block()函数后,返回了自身对象。而T.run是返回了执行的结果。

故而: T.apply的作用除了实现能实现T.run函数的作用外,还可以后续的再对此操作。下面我们看一个例子

例:为TextView设置属性后,再设置点击事件等

val mTvBtn = findViewById(R.id.text) mTvBtn.apply{ text = “kotlin” textSize = 13f … }.apply{ // 这里可以继续去设置属性或一些TextView的其他一些操作 }.apply{ setOnClickListener{ … } }

或者:设置为Fragment设置数据传递

// 原始方法 fun newInstance(id : Int , name : String , age : Int) : MimeFragment{ val fragment = MimeFragment() fragment.arguments?.putInt(“id”,id) fragment.arguments?.putString(“name”,name) fragment.arguments?.putInt(“age”,age)

return fragment }

// 改进方法 fun newInstance(id : Int , name : String , age : Int) = MimeFragment().apply { arguments = Bundle() arguments?.putInt(“id”,id) arguments?.putString(“name”,name) arguments?.putInt(“age”,age) }

3.5、T.also()函数

关于T.also函数来说,它和T.apply很相似,。我们先看看其源码的实现:

public inline fun  T.also(block: (T) -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block(this) return this }

从上面的源码在结合T.apply函数的源码我们可以看出: T.also函数中的参数block函数传入了自身对象。故而这个函数的作用是用用block函数调用自身对象,最后在返回自身对象

这里举例一个简单的例子,并用实例说明其和T.apply的区别

例:

“kotlin”.also { println(“结果:KaTeX parse error: Expected 'EOF', got '}' at position 24: …("-java")}") }̲.also { print…{it.plus(”-php")}") }

“kotlin”.apply { println(“结果:KaTeX parse error: Expected 'EOF', got '}' at position 26: …("-java")}") }̲.apply { prin…{this.plus(”-php")}") }

他们的输出结果是相同的:

结果:kotlin-java 结果:kotlin-php

结果:kotlin-java 结果:kotlin-php

从上面的实例我们可以看出,他们的区别在于,T.also中只能使用it调用自身,而T.apply中只能使用this调用自身。因为在源码中T.also是执行block(this)后在返回自身。而T.apply是执行block()后在返回自身。这就是为什么在一些函数中可以使用it,而一些函数中只能使用this的关键所在

3.6、T.let()函数

public inline fun  T.let(block: (T) -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block(this) }

从上面的源码中我们可以得出,它其实和T.also以及T.apply都很相似。而T.let的作用也不仅仅在使用空安全这一个点上。用T.let也可实现其他操作

例:

“kotlin”.let { println(“原字符串:KaTeX parse error: Expected 'EOF', got '}' at position 42: …t.reversed() }̲.let { printl…it”)     // niltok it.plus(“-java”) }.let { println(“新的字符串:$it”)          // niltok-java }

“kotlin”.also { println(“原字符串:KaTeX parse error: Expected 'EOF', got '}' at position 38: …t.reversed() }̲.also { print…it”)     // kotlin it.plus(“-java”) }.also { println(“新的字符串:$it”)        // kotlin }

“kotlin”.apply { println(“原字符串:KaTeX parse error: Expected 'EOF', got '}' at position 42: …s.reversed() }̲.apply { prin…this”)     // kotlin this.plus(“-java”) }.apply { println(“新的字符串:$this”)        // kotlin }

输出结果看是否和注释的结果一样呢:

原字符串:kotlin 反转字符串后的值:niltok 新的字符串:niltok-java

原字符串:kotlin 反转字符串后的值:kotlin 新的字符串:kotlin

原字符串:kotlin 反转字符串后的值:kotlin 新的字符串:kotlin

3.7、T.takeIf()函数

从函数的名字我们可以看出,这是一个关于条件判断的函数,我们在看其源码实现:

public inline fun  T.takeIf(predicate: (T) -> Boolean): T? { contract { callsInPlace(predicate, InvocationKind.EXACTLY_ONCE) } return if (predicate(this)) this else null }

从源码中我们可以得出这个函数的作用是:传入一个你希望的一个条件,如果对象符合你的条件则返回自身,反之,则返回null

例: 判断一个字符串是否由某一个字符起始,若条件成立则返回自身,反之,则返回null

val str = “kotlin”

val result = str.takeIf { it.startsWith(“ko”)  }

println(“result = $result”)

输出结果为:

result = kotlin

3.8、T.takeUnless()函数

这个函数的作用和T.takeIf()函数的作用是一样的。只是和其的逻辑是相反的。即:传入一个你希望的一个条件,如果对象符合你的条件则返回null,反之,则返回自身。

这里看一看它的源码就明白了。

public inline fun  T.takeUnless(predicate: (T) -> Boolean): T? { contract { callsInPlace(predicate, InvocationKind.EXACTLY_ONCE) } return if (!predicate(this)) this else null }

这里就举和T.takeIf()函数中一样的例子,看他的结果和T.takeIf()中的结果是不是相反的。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)

最后

希望大家能有一个好心态,想进什么样的公司要想清楚,并不一定是大公司,我选的也不是特大厂。当然如果你不知道选或是没有规划,那就选大公司!希望我们能先选好想去的公司再投或内推,而不是有一个公司要我我就去!还有就是不要害怕,也不要有压力,平常心对待就行,但准备要充足。最后希望大家都能拿到一份满意的 offer !如果目前有一份工作也请好好珍惜好好努力,找工作其实挺累挺辛苦的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android) [外链图片转存中…(img-PAb1aU5a-1711937244010)]

最后

希望大家能有一个好心态,想进什么样的公司要想清楚,并不一定是大公司,我选的也不是特大厂。当然如果你不知道选或是没有规划,那就选大公司!希望我们能先选好想去的公司再投或内推,而不是有一个公司要我我就去!还有就是不要害怕,也不要有压力,平常心对待就行,但准备要充足。最后希望大家都能拿到一份满意的 offer !如果目前有一份工作也请好好珍惜好好努力,找工作其实挺累挺辛苦的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-sbDRW71O-1711937244011)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: