当前位置: 首页 > news >正文

【Kotlin】Kotlin函数那么多,你会几个?

目录

  • 标准函数
    • let
    • run
    • with
    • apply
    • also
    • takeIf
    • takeUnless
    • repeat
    • 小结
      • 作用域函数的区别
      • 作用域函数使用场景
  • 简化函数
  • 尾递归函数(tailrec)
  • 扩展函数
  • 高阶函数
  • 内联函数(inline)
    • inline
    • noinline
    • crossinline
  • 匿名函数

标准函数

Kotlin标准库包含几个函数,其唯一目的是在对象上下文中执行代码块。当对提供了lambda表达式的对象调用这样的函数时,它会形成一个临时作用域。在此范围内,您可以访问不带名称的对象。此类函数称为作用域函数。从技术上讲,作用域函数在许多情况下是可以互换使用的。

let

上下文对象可用作参数(it),引用对象时使用it.。返回值是lambda表达式最后一行代码的结果。可用于调用调用链结果上的一个或多个函数。

var user = User()
// 使用此值作为参数调用指定的函数块并返回其结果。
val let = user.let {it.name = "宾有为"it.func = "let"1 // 返回值 1
}
print("let:${user},return lambda result:${let}")

执行结果:

在这里插入图片描述

run

上下文对象可用作接收器(this),引用对象使用this.或直接使用对象值。返回值是lambda表达式最后一行代码的结果。run执行与with相同的操作,但作为上下文对象的扩展函数调用let。当lambda同时包含对象初始化和返回数值时,run非常有用。

var user = User()
// 调用指定的函数块,将此值作为其接收器并返回其结果。
val run = user.run {name = "宾有为"func = "run"1 // 返回值 1
}
print("run:${user}\nreturn lambda result:${run}")

执行结果:

在这里插入图片描述

with

非扩展函数:上下文对象作为参数传递,但在lambda内部,它作为接收器(this)可用。返回值是lambda表达式最后一行代码的结果。建议使用来调用上下文对象上的函数,而不提供lambda结果。

var user = User()
// 以给定的接收器作为其接收器调用指定的函数块,并返回其结果。
val with = with(user) {name = "宾有为"func = "with"1 // 返回值 1
}
print("run:${user}\nreturn lambda result:${with}")

执行结果:

在这里插入图片描述

apply

上下文对象可用作接收器(this),引用对象使用this.或直接使用对象值。返回值是对象本身。对于不返回值且主要对接收器对象的成员进行操作的代码块,请使用applyapply的常见情况是对象配置。

var user = User()
// 使用此值作为其接收器调用指定的函数块,并返回此值。
val apply = user.apply {name = "宾有为"func = "apply"
}
print("also:${apply}\nreturn context object:${apply}")

执行结果:

在这里插入图片描述

also

上下文对象可用作参数(it),引用对象时使用it.。返回值是对象本身。也适用于执行一些将上下文对象作为参数的操作。还可用于需要引用对象而不是其属性和函数的操作,或者不希望从外部范围隐藏此引用时。

var user = User()
// 使用此值作为参数调用指定的函数块并返回此值。
val also = user.also {it.name = "宾有为"it.func = "also"
}
print("also:${user}\nreturn context object:${also}")

执行结果:

在这里插入图片描述

takeIf

takeIf是类似 if 关键字单个对象的过滤函数,使用方式与takeUnless相反。使用对象进行调用时,如果该对象与lambda的条件匹配,takeIf将返回该对象。否则,返回null

var user = User(name = "宾有为", func = null)
val existName = user.takeIf { it.name != null }
val existSex = user.takeIf { it.func != null }
println("existName: $existName, existSex: $existSex")

执行结果:

在这里插入图片描述

takeUnless

takeIf是类似 else 关键字的过滤函数,使用方式与takeIf相反。使用对象进行调用时,如果该对象与lambda的条件匹配,takeIf将返回该对象。否则,返回null

var user = User(name = "宾有为", func = null)
val existName = user.takeUnless { it.name != null }
val existSex = user.takeUnless { it.func != null }
println("existName: $existName, existSex: $existSex")

执行结果:

在这里插入图片描述

repeat

repeat,是一个从0开始循环至指定长度的函数,与for (index in 0 until times) { }执行的结果一致。

// 从0遍历至10
repeat(10){print(it)
}

执行结果:

在这里插入图片描述

小结

Kotlin标准库包含几个函数,其唯一目的是在对象上下文中执行代码块。当对提供了lambda表达式的对象调用这样的函数时,它会形成一个临时作用域。在此范围内,您可以访问不带名称的对象。此类函数称为作用域函数。作用域函数有五个:letrunwithapplyalso

作用域函数的区别

在这里插入图片描述

作用域函数使用场景

函数使用场景
let1、对非空对象执行lambda
2、在局部范围中引入表达式作为变量
with对对象的函数调用进行分组
run1、对象配置和计算结果
2、在需要表达式的地方运行语句
apply1、对象配置和计算结果
2、不返回值且主要对接收器对象的成员进行操作的代码块
also1、执行一些将上下文对象作为参数的操作。
2、需要引用对象而不是其属性和函数的操作
3、不希望从外部范围隐藏此引用时

简化函数

kotlin中,变量可以通过等号赋值,函数同样被允许使用等号进行赋值,这些使用等号赋值的函数就叫做简化函数。

简化函数的编写规范是有所要求的,如果函数表达式只有一行,才可以使用等号赋予函数其表达式。简化函数默认return函数的最后一行代码。

fun main(args: Array<String>) {println(test1())// result:2println(test2())// result:简化函数
}
// 执行表达式 1+1
private fun test1() = 1+1
// 返回表达式"简化函数",简化函数如果有返回类型,表达式的执行结果必须是一个可以返回的类型。
private fun test2() : String = "简化函数"

尾递归函数(tailrec)

kotlin存在一种特殊的递归函数——尾递归函数,指的是函数末尾的返回值重复调用了自身函数。使用时只需要在函数的fun前面加上tailrec关键字,编译器在编译时会自动优化递归,使用循环方式代替递归,从而避免栈溢出的情况,以此提高程序性能。

fun main(args: Array<String>) {print(factorial(5)) // result:120
}// 求 i 的阶乘( i * i-1 )
tailrec fun factorial(i: Int): Int {if (i != 1) {return i * factorial(i - 1)} else {return i}
}

扩展函数

把接收者类型,放到即将添加的函数前面,通过类可以对其调用的函数称为扩展函数。

如图所示,接收者类型写在了test函数的前边,在扩展函数里,使用this引用的是接收者l类型的对象,而非当前Test类。

在这里插入图片描述
如下图所示,通过String类型还无法调用test函数,我们在函数名称的前面加上String类型,再次通过类型就可以引用test函数。

在这里插入图片描述

在这里插入图片描述
扩展函数只能由接收者类型调用,不能通过扩展函数所在的类调用。

在这里插入图片描述

扩展函数不仅可以扩展函数,还可以扩展属性。

val String.lastIndex: Intget() = 0fun main(args: Array<String>) {var a = "aaaa000"print(a.lastIndex) // result:0
}

小知识

  • 扩展函数不可以重写。
  • 扩展函数实质上是静态函数。
  • 在扩展函数里使用this引用的是扩展函数的类型,而不是函数当前所在类。
  • 如果扩展函数在其接收者类型之外声明,则它不能访问接收者privateprotected成员。
  • 扩展函数、属性的代码优先级高于接收者类型原有的函数、对象,等同于重写接收者的同名函数、属性。

高阶函数

高阶函数是将函数作为参数或返回函数的函数。

在以下的示例代码中,testFun1(i: Int, face: (String) -> String)就是一个高阶函数,因为它接受一个函数值作为它的第二个参数。

fun main(args: Array<String>) {testFun1(1) { it ->// 实现业务逻辑,将it给return回去it}
}// face: (String) -> String  等于 调用高阶函数使用的名称: (需要传递的参数类型) -> 返回类型
fun testFun1(i: Int, face: (String) -> String) {// 接收到face返回值,并将其printval value = face("testFun")println("testFun:$value")
}

在实现高阶函数的lambda表达式里(如图main函数对testFun1的调用),若设置有返回值,则默认return最后一行的代码结果,若不设置,则返回Unit

运行结果:

在这里插入图片描述

高阶函数除了上述使用方式之外,还可以根据需求传入不同函数对逻辑进行处理。

fun main(args: Array<String>) {val plusResult = num1AndNum2(20, 30) { n1: Int, n2: Int ->// 执行运算    n1 + n2}println("$plusResult") // result:50val minusResult = num1AndNum2(20, 30) { n1: Int, n2: Int ->// 执行运算n1 - n2}println("$minusResult") // result:-10
}fun num1AndNum2(num1: Int, num2: Int, block: (Int, Int) -> Int): Int {return block(num1, num2)
}

除此之外,高阶函数的lambda表达式还可以拆分成lambda表达式变量、匿名函数,分别以变量、匿名函数的形式传入高阶函数。

fun main(args: Array<String>) {val minusResult = num1AndNum2(20, 30, lambda1)println("$minusResult") // result:-10val aaa = num1AndNum2(20, 30, lambda2) // result:50println("$aaa")val anonymous1 = num1AndNum2(20, 30, a) // result:-10val anonymous2 = num1AndNum2(20, 30, b) // result:50// 匿名函数num1AndNum2(20,30,fun(x,y) = x + y) // result:50
}
// lambda表达式
val lambda1 = { x: Int, y: Int -> x - y }
// lambda表达式
val lambda2: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
// 匿名函数
val a = fun(x : Int, y : Int): Int = x - y
// 匿名函数
val b = (fun(x : Int, y : Int): Int = x + y)fun num1AndNum2(num1: Int, num2: Int, block: (Int, Int) -> Int): Int {return block(num1, num2)
}

内联函数(inline)

inline

lambda表达式在底层被转换成了匿名内部类的实现方式,每调用一次 lambda 表达式,都会创建一个新的匿名类实例,会造成额外的内存和性能开销,但这种开销可以通过inline lambda表达式来消除。使用inline关键字修饰的函数也被称为内联函数。

使用inline关键字,需结合反编译才能看见效果。

fun inlineFun(action: (() -> Unit)){println("inlineFun: 调用前...")action()println("inlineFun: 调用后...")
}fun main(args: Array<String>) {inlineFun {println("inlineFun: 正在调用...")}
}

使用Idea、Android Studio开发工具反编译代码步骤:在开发工具的顶部菜单栏 Tools > Kotlin > Show Kotlin Bytecodes > Decompile。

inlineFun未添加inline函数代码反编译结果:

在这里插入图片描述
inlineFun添加inline函数代码反编译结果:

在这里插入图片描述
通过两次添加inline关键字前后的反编译比对,可以看出inline函数是将表达式转移到调用方,通过这样的方式减少lambda创建新匿名类造成的开销。

当你尝试在没有lambda表达式的函数上使用inline时,编译器则会提示inline对性能预期影响微不足道,应该结合高阶函数一起使用的警告。

Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types.

需要注意的是,inline函数不支持修饰变量(包含持有高阶函数的变量),只能用于修饰高阶函数。

noinline

如果不希望传递给inline函数的所有lambda都被内联,请使用修饰符noinline标记一些不需要inline的函数参数(仅限lambda表达式)。使用noinline的前提是使用的函数必须是inline函数。

inline fun inlineFun(noinline action: (() -> Unit)){println("inlineFun: 调用前...")action()println("inlineFun: 调用后...")
}fun main(args: Array<String>) {inlineFun{println("inlineFun: 调用中...")}
}

添加noinline代码反编译后,“调用中…”的字符并没有被反编译出来,而是用action$iv.invoke();调用函数。

在这里插入图片描述

crossinline

crosinline用于禁止传递给内联函数的lambda中的非局部返回。

在内联函数的lambda表达式里,使用return会中断高阶函数后面代码的执行,讲inline函数有讲解到:inline函数是将表达式转移到调用方,因此下面代码的“调用后”是不会print

inline fun inlineFun(action: (() -> Unit)) {println("inlineFun: 调用前...")action()println("inlineFun: 调用后...")
}fun main(args: Array<String>) {inlineFun {println("inlineFun: 调用中...")return}
}

在这里插入图片描述

使用crossinline关键字,则可以杜绝这种情况。inline函数添加crossinline后,return将会报'return' is not allowed here的错误。

在这里插入图片描述

部分博客把crossinline的含义解释成“检查代码中是否有return,如果有则会执行不通过”。这样的说法是片面的,官方文档已经解释了,是禁止非局部返回。如果高阶函数里面的return不影响到嗲用高阶函数的函数后面代码执行,是可以使用return,如下:

在这里插入图片描述
在这里插入图片描述

匿名函数

省略了函数名字的函数称之为匿名函数。

匿名函数往往结合高阶函数一起使用,匿名函数默认隐式return最后一行代码,写法有以下三种:

val a = fun(str: String): String = "a"
val b = (fun(str: String): String = "b")

参数和返回类型的指定方式与高阶函数相同,如果可以从上下文中推断出参数类型,则可以省略参数类型。如下:

// 匿名函数
println(fun(item) = "c")
// 高阶函数
fun println(str : (String) -> String){println(str("ttt"))
}

匿名函数与lambda表达式类似,写法不同,但执行效果可以是一致的,如下lambda函数等同于上面的匿名函数写法:

var d: (it: String) -> String = { "d" }var e: (String) -> String = { "e" }var f = { it: String -> "f" }

看了好几篇的博客,大部分都是说lambda表达式就是匿名函数,我在kotlin官方文档找到的匿名函数写法并不包含lambda表达式,同时也不知道其它作者所表达的lambda表达式就是匿名函数的依据来自于哪里。

在官方文档的匿名函数介绍里,官方讲解了匿名函数与lambda表达式的区别:lambda表达式和匿名函数之间的另一个区别是非本地返回的行为。没有标签的return语句总是从用fun关键字声明的函数返回。这意味着lambda表达式内的返回将从封闭函数返回,而匿名函数内的返回则从匿名函数本身返回。
在这里插入图片描述

小结

  • 将匿名函数作为参数传递时,将它们放在括号内。允许您将函数放在括号外的速记语法仅适用于 lambda表达式。

参考文档
1、高阶函数
2、标准、作用域函数
3、Kotlin之高阶函数
4、《Kotlin从零到精通》—— 函数的运用
5、Android筑基,Kotlin扩展函数详解——郭霖
6、Kotlin Doc——Extensions
7、Kotlin Keywords and operators

相关文章:

【Kotlin】Kotlin函数那么多,你会几个?

目录标准函数letrunwithapplyalsotakeIftakeUnlessrepeat小结作用域函数的区别作用域函数使用场景简化函数尾递归函数&#xff08;tailrec&#xff09;扩展函数高阶函数内联函数&#xff08;inline&#xff09;inlinenoinlinecrossinline匿名函数标准函数 Kotlin标准库包含几个…...

饲养员喂养动物-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-2】饲养员喂养动物 记得 关注&#xff0c;收藏&#xff0c;评论哦&#xff0c;作者将持续更新。。。。 【案例目标】 案例描述 饲养员在给动物喂食时&#xff0c;给不同的动物喂不同的食物&#xff0c;而且在每次喂食时&#xff0c;动物都会发出欢快的叫声。例如&…...

数据分析:消费者数据分析

数据分析&#xff1a;消费者数据分析 作者&#xff1a;AOAIYI 创作不易&#xff0c;如果觉得文章不错或能帮助到你学习&#xff0c;记得点赞收藏评论一下哦 文章目录数据分析&#xff1a;消费者数据分析一、前言二、数据准备三、数据预处理四、个体消费者分析五、用户消费行为总…...

Transformer论文阅读:ViT算法笔记

标题&#xff1a;An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 会议&#xff1a;ICLR2021 论文地址&#xff1a;https://openreview.net/forum?idYicbFdNTTy 文章目录Abstract1 Introduction2 Related Work3 Method3.1 Vision Transformer3.2…...

Android基础练习解答【2】

文章目录一 填空题二 判断题三 选择题四 简答题一 填空题 1&#xff0e;除了开启开发者选项之外&#xff0c;还需打开手机上的 usb调试 开关&#xff0c;然后才能在手机上调试App。 2&#xff0e;App开发的两大技术路线包括 _原生开发_和混合开发。 3&#xff0e;App工程的编译…...

k8s 搭建

需求&#xff1a;搭建k8s 为后续自动部署做准备进程&#xff1a;安装至少两个ubuntu18.04系统&#xff08;一个master 一到多个 node&#xff09;每个系统上都要装上docker 和 kubernetes安装dockersudo su apt-get update#安装相关插件 apt-get install apt-transport-https c…...

安全运维之mysql基线检查

版本加固 选择稳定版本并及时更新、打补丁。 稳定版本&#xff1a;发行6-12个月以内的偶数版本。 检查方法&#xff1a; 使用sql语句:select version(); 检查结果&#xff1a; 存在问题&#xff1a;当前数据库版本较老需要更新 解决方案&#xff1a;前往http://www.mysql…...

跨境电商卖家敦煌、雅虎、乐天、亚马逊测评自养号的重要性!

作为亚马逊、敦煌、乐天、雅虎等跨境的卖家&#xff0c;这两年以来&#xff0c;面对流量越来越贵的现实&#xff0c;卖家需要更加珍惜每次访问listing页面的流量&#xff0c;把转化做好&#xff0c;把流量尽可能转化为更多的订单。 提升转化率的技巧 提升产品转化率&#xff0…...

Python 之 Matplotlib xticks 的再次说明、图形样式和子图

文章目录一. 改变 x 轴显示内容 xticks 方法再次说明1. x 轴是数值型数据2. 将 x 轴更改为字符串3. 总结二. 其他元素可视性1. 显示网格&#xff1a;plt.grid()2. plt.gca( ) 对坐标轴的操作三. plt.rcParams 设置画图的分辨率&#xff0c;大小等信息四. 图表的样式参数设置1. …...

3.InfluxDB WEB使用

结合telegraf做指标数据收集 点击 Load Data -> Telegraf 配置界面 influxDB支持在WEB-UI中生成配置文件 然后利用telegraf通过远程URL请求的方式进行获取 点击CREATE CONFIGURATION 创建telegraf配置文件 选择Bucket InfluxDB提供了很多配置好的监控模板供用户选择 可以…...

git冲突合并

一、版本说明 dev&#xff1a;本地仓库中的dev分支 master&#xff1a;本地仓库中的master分支 remotes/origin/master和origin/master&#xff1a;都是远程仓库上的master分支 二、一个解决冲突的常规流程 1、前提条件&#xff1a;不能在master分支上修改任何文件。master分支…...

项目自动化构建工具make/Makefile

目录 make/Makefile概念和关系 make/Makefie的使用 一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的规则来指定&#xff0c;哪些文件需要先编译&#xff0c;哪些文件需要后编译&#xff0c;哪些文件需要重…...

双目客流统计方案的应用原理

双目客流统计客流摄像头采用立体视觉技术实现高度统计功能。基于视差原理。利用双镜头摄取的两幅图像的视差&#xff0c;构建三维场景&#xff0c;在检测到运动目标后。通过计算图像对应点间的位置偏差。获取目标的三维信息&#xff0c;在深度图像中对目标的检测与追踪&#xf…...

python魔术方法(二)

__getattr__() class A:def __getattr__(self,name):print(f"getting {name}")raise AttributeErroro A() print(o.test)程序调用一个对象的属性&#xff0c;当这个属性不存的时候希望程序做些什么&#xff0c;这里我们打印希望的属性&#xff0c;并且抛出异常 __…...

cmd for命令笔记

语法 help for输出如下&#xff1a; 对一组文件中的每一个文件执行某个特定命令。 FOR %variable IN (set) DO command [command-parameters] %variable 指定一个单一字母可替换的参数。 (set) 指定一个或一组文件。可以使用通配符。 command 指定对每个文件执行的命令。 c…...

4.1 Filter-policy

1. 实验目的 熟悉Filter-policy的应用场景掌握Filter-policy的配置方法2. 实验拓扑 Filter-policy实验拓扑如图4-5所示: 图4-5:Filter-policy 3. 实验步骤 (1) 网络连通性 R1的配置 <Huawei>system-vi…...

day15_常用类

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、代码块[了解] 三、API 四、Object 五、包装类 六、数学和随机 零、 复习昨日 抽象接口修饰符abstractinterface是不是类类接口属性正常属性没…...

【网络原理5】IP协议篇

目录 IP协议报头 4位版本号 4位首部长度 8位服务类型(TOS) 16位总长度 IP拆包 16位标识、3位标志、13位片偏移​编辑 8位生存时间(TTL) 8位协议 16位首部校验和 网络地址管理 32位源ip&32位目的ip 方案一:动态分配ip地址 方案2:NAT网络地址转换(使用一个ip代…...

Unity导出WebGL工程,并部署本地web服务器

WebGL打包 设置修改 在Build Settings->PlayerSettings->Other Settings->Rendering 将Color Space 设置为Gamma 将Lightmap Encoding 设置为NormalQuality 在Build Settings->PlayerSettings->Publishing Settings 勾选Decompression Fallback 打包 完成配…...

蓝桥杯考试总结汇总

一进考场设置devc快捷键 设置注释和取消注释快捷键设置代码自动补全快捷键开启devc调试功能&#xff0c;详细可以看怎么开调试功能https://blog.csdn.net/hz18790581821/article/details/78418648比赛过程中&#xff0c;如果不相信自己是否做对&#xff0c;没有把握的&#xf…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...