【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.
或直接使用对象值。返回值是对象本身。对于不返回值且主要对接收器对象的成员进行操作的代码块,请使用apply
。apply
的常见情况是对象配置。
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
表达式的对象调用这样的函数时,它会形成一个临时作用域。在此范围内,您可以访问不带名称的对象。此类函数称为作用域函数。作用域函数有五个:let
、run
、with
、apply
和also
。
作用域函数的区别
作用域函数使用场景
函数 | 使用场景 |
---|---|
let | 1、对非空对象执行lambda 2、在局部范围中引入表达式作为变量 |
with | 对对象的函数调用进行分组 |
run | 1、对象配置和计算结果 2、在需要表达式的地方运行语句 |
apply | 1、对象配置和计算结果 2、不返回值且主要对接收器对象的成员进行操作的代码块 |
also | 1、执行一些将上下文对象作为参数的操作。 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
引用的是扩展函数的类型,而不是函数当前所在类。 - 如果扩展函数在其接收者类型之外声明,则它不能访问接收者
private
或protected
成员。 - 扩展函数、属性的代码优先级高于接收者类型原有的函数、对象,等同于重写接收者的同名函数、属性。
高阶函数
高阶函数是将函数作为参数或返回函数的函数。
在以下的示例代码中,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小结作用域函数的区别作用域函数使用场景简化函数尾递归函数(tailrec)扩展函数高阶函数内联函数(inline)inlinenoinlinecrossinline匿名函数标准函数 Kotlin标准库包含几个…...
饲养员喂养动物-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)
【案例4-2】饲养员喂养动物 记得 关注,收藏,评论哦,作者将持续更新。。。。 【案例目标】 案例描述 饲养员在给动物喂食时,给不同的动物喂不同的食物,而且在每次喂食时,动物都会发出欢快的叫声。例如&…...
数据分析:消费者数据分析
数据分析:消费者数据分析 作者:AOAIYI 创作不易,如果觉得文章不错或能帮助到你学习,记得点赞收藏评论一下哦 文章目录数据分析:消费者数据分析一、前言二、数据准备三、数据预处理四、个体消费者分析五、用户消费行为总…...
Transformer论文阅读:ViT算法笔记
标题:An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 会议:ICLR2021 论文地址:https://openreview.net/forum?idYicbFdNTTy 文章目录Abstract1 Introduction2 Related Work3 Method3.1 Vision Transformer3.2…...
Android基础练习解答【2】
文章目录一 填空题二 判断题三 选择题四 简答题一 填空题 1.除了开启开发者选项之外,还需打开手机上的 usb调试 开关,然后才能在手机上调试App。 2.App开发的两大技术路线包括 _原生开发_和混合开发。 3.App工程的编译…...
k8s 搭建
需求:搭建k8s 为后续自动部署做准备进程:安装至少两个ubuntu18.04系统(一个master 一到多个 node)每个系统上都要装上docker 和 kubernetes安装dockersudo su apt-get update#安装相关插件 apt-get install apt-transport-https c…...
安全运维之mysql基线检查
版本加固 选择稳定版本并及时更新、打补丁。 稳定版本:发行6-12个月以内的偶数版本。 检查方法: 使用sql语句:select version(); 检查结果: 存在问题:当前数据库版本较老需要更新 解决方案:前往http://www.mysql…...
跨境电商卖家敦煌、雅虎、乐天、亚马逊测评自养号的重要性!
作为亚马逊、敦煌、乐天、雅虎等跨境的卖家,这两年以来,面对流量越来越贵的现实,卖家需要更加珍惜每次访问listing页面的流量,把转化做好,把流量尽可能转化为更多的订单。 提升转化率的技巧 提升产品转化率࿰…...
Python 之 Matplotlib xticks 的再次说明、图形样式和子图
文章目录一. 改变 x 轴显示内容 xticks 方法再次说明1. x 轴是数值型数据2. 将 x 轴更改为字符串3. 总结二. 其他元素可视性1. 显示网格:plt.grid()2. plt.gca( ) 对坐标轴的操作三. plt.rcParams 设置画图的分辨率,大小等信息四. 图表的样式参数设置1. …...
3.InfluxDB WEB使用
结合telegraf做指标数据收集 点击 Load Data -> Telegraf 配置界面 influxDB支持在WEB-UI中生成配置文件 然后利用telegraf通过远程URL请求的方式进行获取 点击CREATE CONFIGURATION 创建telegraf配置文件 选择Bucket InfluxDB提供了很多配置好的监控模板供用户选择 可以…...
git冲突合并
一、版本说明 dev:本地仓库中的dev分支 master:本地仓库中的master分支 remotes/origin/master和origin/master:都是远程仓库上的master分支 二、一个解决冲突的常规流程 1、前提条件:不能在master分支上修改任何文件。master分支…...
项目自动化构建工具make/Makefile
目录 make/Makefile概念和关系 make/Makefie的使用 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重…...
双目客流统计方案的应用原理
双目客流统计客流摄像头采用立体视觉技术实现高度统计功能。基于视差原理。利用双镜头摄取的两幅图像的视差,构建三维场景,在检测到运动目标后。通过计算图像对应点间的位置偏差。获取目标的三维信息,在深度图像中对目标的检测与追踪…...
python魔术方法(二)
__getattr__() class A:def __getattr__(self,name):print(f"getting {name}")raise AttributeErroro A() print(o.test)程序调用一个对象的属性,当这个属性不存的时候希望程序做些什么,这里我们打印希望的属性,并且抛出异常 __…...
cmd for命令笔记
语法 help for输出如下: 对一组文件中的每一个文件执行某个特定命令。 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调试功能,详细可以看怎么开调试功能https://blog.csdn.net/hz18790581821/article/details/78418648比赛过程中,如果不相信自己是否做对,没有把握的…...
备战蓝桥杯【二维前缀和】
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
阿里P6细谈Python简易接口自动化测试框架设计与实现,我直呼内行
1、开发环境 操作系统:Ubuntu18 开发工具:IDEAPyCharm插件 Python版本:3.6 2、用到的模块 requests:用于发送请求 xlrd:操作Excel,组织测试用例 smtplib,email:发送测试报告 l…...
数据库存储
RAID DSL : Domain Spesic Language 专用领域语言 单机存储 一切皆Key-Value 本地文件系统 一切皆文件 Ceph - 分布式存储 关系型数据库通用组件 Query Engine :解析query,生成查询计划Txn Manager :事务并发管理Lock Man…...
hive学习笔记
一、Hive基本概念1.1 hive是什么hive是基于hadoop的一个数仓分析工具,hive可以将hdfs上存储的结构化的数据,映射成一张表,然后让用户写HQL(类SQL)来分析数据tel up down 1383838438 1345 1567 138383…...
7大体系防作弊,牛客放大招了!严肃笔试客户端上线!
如果问起学生对在线笔试的印象,“不公平”和“不服气”占了半壁江山。学生认为很多企业的在线笔试系统并不完善。原因一,不能有效地规避部分学生的作弊行为;原因二,在线考试系统不稳定,bug频出,导致笔试发挥…...
R语言广义可加模型在空气环境污染方面的应用(1)
粉丝私信我希望复制一篇文章的图片,图片来源于文章:Wu C, Yan Y, Chen X, Gong J, Guo Y, Zhao Y, Yang N, Dai J, Zhang F, Xiang H. Short-term exposure to ambient air pollution and type 2 diabetes mortality: A population-based time series st…...
CSDN 编程竞赛二十九期题解
竞赛总览 CSDN 编程竞赛二十九期:比赛详情 (csdn.net) 竞赛题解 题目1、订班服 小A班级订班服了!可是小A是个小糊涂鬼,整错了好多人的衣服的大小。小A只能自己掏钱包来补钱了。小A想知道自己至少需要买多少件衣服。 #include <cstdio…...
基于STM32采用CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试
一、前言 在STM32项目开发中,经常会用到存储芯片存储数据。 比如:关机时保存机器运行过程中的状态数据,上电再从存储芯片里读取数据恢复;在存储芯片里也会存放很多资源文件。比如,开机音乐,界面上的菜单图…...
K_A12_007 基于STM32等单片机驱动AS608光学指纹识别模块 OLED0.96显示
K_A12_007 基于STM32等单片机驱动AS608光学指纹识别模块 OLED0.96显示一、资源说明二、基本参数参数引脚说明三、驱动说明对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCAS608光学指纹模块1.2、STM32F103C8T6AS608光学指纹模块五、基础知识学习与相关资料下载六、视…...
map和set介绍及其底层模拟实现
致努力前行的人: 要努力,但不要着急,繁花锦簇,硕果累累都需要过程! 目录 1.关联式容器 2.键值对 3.树形结构的关联式容器 3.1set的介绍 3.2set的使用 3.3multiset的使用 3.4map的使用 3.5multimap的使用 4.常见的面试题…...
建设银行官方网站广州/百度账号管家
对于pca , nmds, pcoa 这些排序分析来说,我们可以从图中看出样本的排列规则,比如分成了几组。 为例样本分组更加的直观,我们可以根据实验设计时的样本分组情况,对属于同一个group的样本添加1个椭圆或者其他多边形。 新版本的ggplo…...
做富集的网站/百度广告登录入口
Hello,今天教大家用中继器结合网易云音乐制作做一个高保真的音乐播放器,这个原型可以真实播放网易云里的音乐(音频),能够切换播放歌曲和显示对应的内容。制作完成后,该模板使用简单,复用性强。再…...
太原做网站要多少钱呢/培训机构营业执照如何办理
点击上方“蓝色字”可关注我们!暴走时评:区块链作为欧洲最强大的经济体,德国对区块链技术在各个领域的应用都表现出了“极大的兴趣”,包括汽车、制药、能源和公共部门管理等。作者:Yogita Khatri 翻译:May…...
兰州网站哪里做/广州seo关键词优化费用
这次要为我的python程序加上数据库,主要是实现从mysql中查询出数据并在页面上显示出来。 首先是mysql的配置文件config.py host"127.0.0.1" user"root" password"" charset"utf8" database"service" port3306 然…...
想要黑掉一个网站 要怎么做/河南网站seo靠谱
夜光序言: 红尘如何 荼蘼几度光阴 我曾摆渡 种下几世之姻 你曾说过 甘愿地老天荒 为何只剩 我一人独守空城 正文: # Genius:matchSim.py from random import * def main():printIntro()probA,probB,n getInputs()winsA, winsB si…...
怀来住房和城乡建设委员会网站/最近一周新闻
转载自 http://blog.csdn.net/edricbjtu/article/details/41082597 转载于:https://www.cnblogs.com/minesweeper/p/5937474.html...