Kotlin谷歌已经给我们封装了一些高阶函数。
代码如下(这里为了展示代码全貌,忽视androidStudio的代码优化提示):
class A {
val a = 1
val b = “b”
}
fun testRun() {
//run方法有两种用法,一个是不依赖对象,也就是作为全局函数
run {//我可以规定返回值的类型
println(“我是全局函数”)
“返回值”
}
val a = A()
//另一种则是 依赖对象
a.run<A,String> {//这里同样可以规定返回值的类型
println(this.a)
println(this.b)
“返回值”
}
}
fun main() {
testRun()
}
如上所示:
run函数分为两类
不依赖对象的全局函数。
依赖对象的"类似"扩展函数。
两者都可以规定返回值类型(精通泛型的话,这里应该不难理解,泛型下一节详解)。
阅读源码:
@kotlin.internal.InlineOnly
public inline fun run(block: () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
run函数被重载,参数有所不同
所以,前者不需要依赖对象,后者必须依赖对象(因为它是T类的"扩展函数")
使用场景
根据run方法的特性,无论是不是依赖对象,它都是封装了一段代码,而且还是inline的。所以:
run {
println(“这是一段代码逻辑很相近的代码段”)
println(“但是我不想把他独立成一个方法”)
println(“又担心别人会随便改”)
println(“所以用run方法把他们放在同一个作用域中”)
println(“小组中其他人看到这段,就知道不要把无关代码插进来”)
}
fun testRun2(param1: String, param2: String, param3: String) {
//我想让这几个参数都不为空,如果检查是空,就不执行方法主体
val checkRes: Boolean = run {
when {
param1.isNullOrEmpty() -> {
false
}
param2.isNullOrEmpty() -> {
false
}
param3.isNullOrEmpty() -> {
false
}
else -> true
}
}
if (checkRes){
println(“参数检查完毕,现在可以继续接下来的操作了”)
}else{
println(“参数检查不通过,不执行主体代码”)
}
}
fun main() {
testRun2(“1”, “2”, “”)
}
main运行结果:
小结论
run方法在整合小段代码的功效上,还是很实用的
上面列举出来的这些系统高阶函数原理上都差不多,只是使用场景有区别,因此除了run之外,其他的不再详解,而只说明使用场景。
和run只有一个区别,run是返回block()执行之后的返回值,而,apply 则是返回this,因此 apply必须依赖对象。而由于返回了this,因此可以连续apply调用。
fun testApply() {
val a = A()
a.apply {
println(“如果一个对象要对它进行多个阶段的处理”)
}.apply {
println(“那么多个阶段都挤在一起则容易混淆,”)
}.apply {
println(“此时可以用apply将每一个阶段分开摆放”)
}.apply {
println(“让程序代码更加优雅”)
}
}
fun main() {
testApply()
}
下面的代码应该都很眼熟,Glide图片加载框架的用法,with(context)然后链式调用
Glide.with(this).load(image).asGif().into(mImageView);
Kotlin中的with貌似把这一写法发扬光大了(只是类比,不用深究),场景如下:
class A {
val a = 1
val b = “b”
fun showA() {
println(“$a”)
}
fun showB() {
println(“$a $b”)
}
}
fun testWith() {
val a = A()
with(a) {
println(“作用域中可以直接引用创建出的a对象”)
this.a
this.b
this.showA()
this
}.showB()
}
fun main() {
testWith()
}
细节
also和with一样,必须依赖对象,返回值为this。因此它也支持链式调用,它和apply的区别是:
apply的block,没有参数,但是 also 则将this作为了参数。这么做造成的差异是:
作用域 { } 内调用当前对象的方式不同。
class A {
val a = 1
val b = “b”
fun showA() {
println(“$a”)
}
fun showB() {
println(“$a $b”)
}
}
fun testApply() {
A().apply {
this.showA()
println(“=======”)
}.showB()
}
fun testAlso() {
A().also {
it.showA()
println(“=======”)
}.showB()
}
apply 必须用this.xxx
, also则用 it.xxx
.
类比到run:
public inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
public inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
只有一个区别:run的block执行不需要参数,而let 的block执行时需要传入this。
造成差异为:
A().run {
println(“最后一行为返回值”)
this
}.showA()
A().let {
println(“最后一行为返回值”)
it
}.showA()
run{} 作用域中 只能通过this.xxx操作当前对象,let 则用 it.xxx
这两个作用相反,并且他们必须依赖对象。看源码:
public inline fun T.takeIf(predicate: (T) -> Boolean): T? {
return if (predicate(this)) this else null
}
public inline fun T.takeUnless(predicate: (T) -> Boolean): T? {
return if (!predicate(this)) this else null
}
predicate 是 (T)->Boolean 类型的lambda表达式,表示断言判断,如果判断为true,则返回自身,否则返回空
class A {
val a = 0
val b = “b”
fun showA() {
println(“$a”)
}
fun showB() {
println(“$a $b”)
}
}
fun testTakeIfAndTakeUnless() {
println(“test takeIf”)
A().takeIf { it.a > 0 }?.showB()
println(“==========”)
println(“test takeUnless”)
A().takeUnless { it.a > 0 }?.showB()
}
fun main() {
testTakeIfAndTakeUnless()
}
执行结果:
test takeUnless
0 b
takeIf / takeUnless
适用于将条件判断的代码包在一个作用域{}中,然后 用 ?.xxxx的安全调用符 来 执行对象操作。
repeat是 多次循环的傻瓜版写法。
fun testRepeat() {
repeat(10) {
print("$it ")
}
}
fun main() {
testRepeat()
}
执行结果:
0 1 2 3 4 5 6 7 8 9
lazy的作用是: 延迟初始化val定义的常量。
class B {
val i: Int by lazy {
println(“执行i初始化”)
20
}
init {
println(“构造函数执行”)
}
}
如果只是初始化B对象,却没有使用到变量i
, 那么延迟初始化不会执行。
fun main() {
B()
}
执行结果:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
d开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
[外链图片转存中…(img-3pI5nxxr-1712776104807)]
[外链图片转存中…(img-nqFxiUyr-1712776104808)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
文章浏览阅读748次。总结起来大概有5种做法:将要处理的文字写到一个资源文件,如string.xml(使用html用法格式化)当文字中出现URL、E-mail、电话号码等的时候,可以将TextView的android:autoLink属性设置为相应的的值,如果是所有的类型都出来就是**android:autoLink="all",当然也可以在java代码里 做,textView01.setAutoLinkMask(Li..._qaction::settext 无法添加下划线
文章浏览阅读6.3k次,点赞2次,收藏10次。摘要: 背景 随着近几年物联网的发展,时序数据迎来了一个不小的爆发。从DB-Engines上近两年的数据库类型增长趋势来看,时序数据库的增长是非常迅猛的。在去年我花了比较长的时间去了解了一些开源时序数据库,写了一个系列的文章(综述、HBase系、Cassandra系、InfluxDB、Prometheus),感兴趣的可以浏览。背景随着近几年物联网的发展,时序数据迎来了一个不小的爆发。从DB..._tablestore 时间类型处理
文章浏览阅读5.7k次,点赞8次,收藏49次。可以编译成功但是运行时段错误查找原因应该是ROS noetic版本中自带的OpenCV4和VINS-mono中需要使用的OpenCV3冲突的问题。为了便于查找问题,我只先编译feature_tracker包。解决思路历程:o想着把OpenCV4相关的库移除掉,但是发现编译feature_tracker的时候仍然会关联到Opencv4的库,查找原因是因为cv_bridge是依赖opencv4的,这样导致同时使用了opencv3和opencv4,因此运行出现段错误。oo进一步想着(1)把vins-mon_uabntu20.04安装vins-mono
文章浏览阅读3.6k次,点赞3次,收藏12次。创龙TL6748开发板中,EMIFA模块使用默认的PLL0_SYSCLK3时钟,使用AISgen for D800K008工具加载C6748配置文件C6748AISgen_456M_config(Configuration files,在TL_TMS6748/images文件夹下),由图可以看到DIV3等于4,注意这里的DIV3就是实际的分频值(x),而不是写入相应PLL寄存器的值(x-1)。_tms 6748
文章浏览阅读5.9k次,点赞4次,收藏13次。转载请说明出处:eigen稀疏矩阵拼接(块操作)eigen稀疏矩阵拼接(块操作)关于稀疏矩阵的块操作:参考官方链接 However, for performance reasons, writing to a sub-sparse-matrix is much more limited, and currently only contiguous sets of columns..._稀疏矩阵拼接
文章浏览阅读946次,点赞19次,收藏19次。波束形成是天线阵列信号处理中的一项关键技术,它通过对来自不同方向的信号进行加权求和,来增强特定方向的信号并抑制其他方向的干扰。本文介绍了两种基于 Capon 和信号子空间的变形算法,即最小方差无失真响应 (MVDR) 算法和最小范数算法,用于实现波束形成。这些算法通过优化波束形成权重向量,来最小化波束形成输出的方差或范数,从而提高波束形成性能。引言波束形成在雷达、声纳、通信和医学成像等众多应用中至关重要。它可以增强目标信号,抑制干扰和噪声,提高系统性能。
文章浏览阅读3.4w次。转自:http://www.linuxidc.com/Linux/2017-07/145335.htm使用Ubuntu开发已经有些时间了。写下这篇文章,希望记录下这一年的小小总结。使用Linux开发有很多坑,同时也有很多有趣的东西,可以编写一些自动化脚本,添加定时器,例如下班定时关机等自动化脚本,同时对于服务器不太了解的朋友,建议也可以拿台Linux来实践下,同时Ubuntu在Androi_ubuntu开发推荐软件
文章浏览阅读2.2k次。一,问题 nginx反向代理后,在应用中取得的ip都是反向代理服务器的ip,取得的域名也是反向代理配置的url的域名,解决该问题,需要在nginx反向代理配置中添加一些配置信息,目的将客户端的真实ip和域名传递到应用程序中。二,解决 Nginx服务器增加转发配置 proxy_set_header Host $host;_nginx获取到的是交换机的ip
文章浏览阅读1.4k次。Wireshark TCP数据包跟踪 还原图片 WinHex简单应用 _wireshark抓包还原图片
文章浏览阅读1.5k次。Win8下安装VS2012时,蓝屏,报错WHEA_UNCORRECTABLE_ERROR(P.S.新的BSOD挺有创意":("),Google之,发现[via]需要BIOS中禁用Intel C-State,有严重Bug的嫌疑哦原因有空再看看..._win8.1 whea_uncorrectable_error蓝屏代码
文章浏览阅读919次,点赞21次,收藏22次。科大讯飞是一家专业从事智能语音及语音技术研究、软件及芯片产品开发、语音信息服务的软件企业,语音技术实现了人机语音交互,使人与机器之间沟通变得像人与人沟通一样简单。语音技术主要包括语音合成和语音识别两项关键技术。此外,语音技术还包括语音编码、音色转换、口语评测、语音消噪和增强等技术,有着广阔的应用。_科大讯飞培训案例
文章浏览阅读4.7k次。Perl是一个高阶程式语言,由 Larry Wall和其他许多人所写,融合了许多语言的特性。它主要是由无所不在的 C语言,其次由 sed、awk,UNIX shell 和至少十数种其他的工具和语言所演化而来。Perl对 process、档案,和文字有很强的处理、变换能力,ActivePerl是一个perl脚本解释器。其包含了包括有 Perl for Win32、Perl for ISAPI、PerlScript、Perl。_perl下载