用到是IDEA免费版本。新建一个Kotlin项目。

取个名字。

最后新建一个.kt文件,就可以开始使用kotlin了。

选择创建File。之后就会生成一个.kt的文件。

HelloWorld程序:
fun main() {
var str:String="Hello"
println(str)
}
手动编译运行:
执行下面的代码会生成一个叫HelloKt.class的字节码文件,非常奇怪的是,命令行并没有提供什么参数来修改这个生成的文件名字。
kotlinc Hello.kt
通过kotlin命令行来执行字节码文件:
kotlin HelloKt.class
也可以通过下面的代码生成jar文件,然后通过java -jar来运行
kotlinc Hello.kt -d hello.jar
java -jar hello.jar
下面的代码声明了一个String类型的变量,通过var关键字来声明变量,和java相比,这个写法好像非常的麻烦,多了var关键字还多了冒号,而且写的顺序也不一样,类型声明在后面,据说这个语法是从TypeScript那里学过来的,对TypeScript(JS)不熟。既然设计成这样,一定是有他的好处的。实际上,类型可以省略,kotlin会自动帮我们推导出来。
fun main() {
var str:String="Hello"
println(str)
}
省略后的写法:
也就是不管什么类型,都可以声明为var类型。对于开发者来说,还是节省了一点时间的,虽然牺牲了一点效率,因为倒推类型肯定需要额外的内部操作。
fun main() {
var str="Hello"
println(str)
}
下面的代码声明了一个String类型的变量,但是编译器会给一个警告,说"Hello"是一个只读变量,可以用val声明。注意是最后一个字母是L而不是R,var和val是两个关键字。var可以用来声明一般的变量,val用来声明只读变量,类似于java的final关键字。
var str="Hello"
用val声明:
val str="Hello"
注意这个只读并不等于常量,常量是用另一个关键字const来修饰的。
常量只能声明在方法外部,在方法内部是不能声明常量的。
const val MAX=1024
fun main() {
println(MAX)
}
在kotlin中,const相对于java的static final。我们可以通过双击shitf,输入kotlin bytecode查看字节码信息。
public final static I MAX = 1024
我们知道Java有引用类型和基本数据类型这两种类型。引用类型放在堆里面,一般是java对象。而kotlin只有一种类型,也就是引用类型,但是在编译的时候,还是会转化为基本类型。
val age=10
在字节码里面的LOCALVARIABLE I代表int类型。也就是会转化为基本数据类型。字节码内容了解一下就行。
LOCALVARIABLE age I L1 L6 0
和Java的用法一样,就不写了。
字面意思就是范围表达式,用到的关键字是in。下面这个例子很好的说明了使用的in关键字的用法。不光可以指定数字,还可以指定数组或者集合。
val score=66
if (score in 0..60){
println("bad")
}else if (score in 61..80){
println("not bad")
}else{
println("good")
}
相对于Java的switch表达式,但更加简洁,推荐将所有的if else表达式都转化成when的形式,when表达式在kotlin中是非常常用的。
下面的代码对比Java的switch语句少了case和default关键字看起来简洁了非常多。
而且可以返回多种数据类型,这里返回了String类型的“男”,“女”,和int类型的-1。
返回类似是Any类型,这个有点类似Java的Object类型。->实际上是一个lambda表达式。如果只有单行可以直接返回结果,不用写return;
val gender=3;
val result:Any=when(gender){
1->"男"
2->"女"
else-> -1
}
println(result)
如果lambda表达式存在多行,那么需要加一个大括号{}。
val gender=3;
val result=when(gender){
1->"男"
2->"女"
else-> {
println("未知")
println("程序退出")
}
}
println(result)
程序最后输出如下,kotlin.Unit类似于Java的void,因为println并没有返回值。
未知
程序退出
kotlin.Unit
String模板就是String的拼接。在Java中,我们用++拼接字符串,这个实际上是非常麻烦的。很多语言都支持用 符 号 拼 接 内 容 , 用 符号拼接内容,用 符号拼接内容,用{}拼接表达式。
用$拼接内容:
val animal="dog"
val color="yellow"
println("The $animal's color is $color")
输出内容:
The dog's color is yellow
用${}拼接表达式:
val animal="dog"
val color="yellow"
val age=10
println("The $animal's is $color and ${if(age>5) "old" else "young"}")
输出内容:
The dog's is yellow and old
kotlin的函数头和Java还是差别非常大的,priavate表示权限,默认是oublic,fun是函数声明关键字,括号里面是参数列表,最后的:Boolean表示返回类型。
可以看到参数列表和返回值的顺序和Java是相反的,这实际上是更加符合逻辑的,先传输入再确定输出类型,也就是输入输出。只是Java用习惯了,也就习以为常了。
private fun doSomething(i:Int ,s:String):String{
return "resultCode";
}
函数调用
直接调用就可以,不需要创建对象。
fun main() {
val flag = doSomething(5, "abc")
println(flag)
}
参数还可以给默认值,只是Java所没有的,Java有固定的默认值。kotlin支持指定默认值。
private fun doSomething2(a:Int=2,s:String="null"):String{
return "$a $s";
}
fun main() {
//没有传任何参数
val result = doSomething2()
println(result)
}
输出结果:
2 null
具名的意思就是在传入参数的时候可以指定参数的名字,这样的目的是增加可读性,因为光传参数,不知道这个参数是干嘛用的,可能传错位置,可读性也很差。
例如下面的代码,代码一的位置,写了参数的名字是age,和name,这样就不会搞错参数位置了,可读性非常强。但是,IDEA是支持参数类型提示的,可以直接显示参数类型,这相对于是IDEA已经实现的功能,可能就是为了弥补Java没有这个功能而设计的。
fun main() {
//代码一
var flag=doSomething(age=5,name="abc")
}
private fun doSomething(age:Int,name:String):Boolean{
return true;
}
在Java中没有返回类型就返回void类型,但在泛型的时候,这个概念就有点矛盾。kotlin用kotlin.Unit这个类型表示没有返回类型。在kotlin中,如果没有返回类型,那么函数的返回类型可以不用写任何类型,也不用写void,kotlin根本就没有void这个关键字。
fun main() {
println(testUnit(5,"abc"))
}
private fun testUnit(age:Int,name:String) {
}
输出:
kotlin.Unit
在函数名上面加一个反引号,kotlin支持这种写法,这样做的主要目的是为了和Java的交互性。Java和Kotlin是可以无缝调用的,但因为Java和Kotlin的关键字不同,可能一些方法名在Java是合法的,但到了Kotlin就变成非法,这时候就可以加反引号解决。
例如下面的Java代码,声明了一个is方法,这在Java里面是合法的,但如果在kotlin里面要调用这个方法就不行了,因为is在Kotlin里面是一个关键字。
public class Data {
public static void is(){
}
}
这时候在函数名上加一个反引号就可以解决这个问题。这样is就不被当作是关键字而可以在kotlin里面使用了。
//在kotlin中调用
Data.`is`()
有趣的是,加了反引号之后,方法名甚至可以写空格例如下面的代码。
private fun `first we calculate add`(a: Int,b:Int):Int{
return a+b;
}
private fun `second we calculate sub`(a: Int,b:Int):Int{
return a-b;
}
fun main() {
val add= `first we calculate add`(1,2)
val sub = `second we calculate sub`(1, 2)
println("$add $sub")
}
用自然语言编程不再是梦。当然这个应该是用不太上,主要还是为了解决和Java的交换问题,写类似注释的方法名还是交给注释比较好。
我们举String的count方法为例,count方法有两个重载,第一个无参函数非常好理解,第二个重载声明如下,要求我们传入一个lambda表达式,这个表达式传入char,返回boolean(判断条件),最后整个函数返回一个int,也就是我们指定的char字符有多少个。
public inline fun CharSequence.count(predicate: (Char) -> Boolean): Int
var count="Kotlining".count()
var countI = "Kotlining".count({letter -> letter == 'i'} )
println(count)
println(countI)
输出
9
2
这个和C语言的函数指针是非常像似的,但java是移除了这些特性的。
我们看下面的代码,第一次看这个代码可能非常的奇怪,看着像lambda表达式,又不完全是,其实这里的关键就是理解()->String的含义。这个语法是lambda表达式,但这里的真正含义是匿名内部类类型,并且这个匿名内部类返回String类型。顺理成章的,我们定义的变量result的类型也就变成了String类型。注意是一个类型声明,而不是lambda表达式实体,lambda表达式的实体是{}里面的内容。
var result:()->String={
val animal="dog"
"This is $animal"
}
看下和lambda表达式的对比:
下面是java的lambda表达式.一个非常明显的区别就是kotlin的匿名内部类没有return,而且在里面也是不可以写return的,这是因为他默认返回类型是表达式的最后一行。为了实现这个功能,就必须显示的声明类型,因为可能返回一个类对象。
()->{
val animal="dog"
return "This is $animal"
}
当然也是可以带参数的。在()里面声明参数类型,在{}开头可以写具体名字。写法还是非常飘逸的。
val result2:(String,Int)->String={
name,age->
val animal="dog"
"This is $animal , name is $name , age is $age"
}
println(result2("tom",5))
输出:
This is dog , name is tom , age is 5
还有一种类型推断的写法,如下,参数我们还是要指定类型的,但返回值可以推断出来。感觉这种写法更简洁一点,前面的写法更标准一些。
val result4 = { name: String, age: Int ->
val animal = "dog"
"This is $animal , name is $name , age is $age"
}
接着上小节,如果参数只有一个的时候,我们可以不写具体的参数名字,kotlin默认为我们提供了一个it关键字,可以直接使用这个关键字当参数变量名称。
val result3:(String)->String={
val animal="dog"
"This is a $animal , name is $it."
}
println(result3("tom"))
输出:
This is a dog , name is tom.
下面这个函数的功能是显示学生信息,包括学生的姓名和身份证,第二个参数是一个函数类型,没错可以将一个函数做为参数传进来。这个函数可以合成学生的身份证,身份证由邮政编码,生日,编号构成。
private fun showStudentInfo(name: String, getId: (Int,Int,Int) -> String): String {
//必须用大括号
return "$name's id is ${getId(300027,20001212,1001)}"
}
var getId = { code: Int, birth: Int, num: Int ->
"$code$birth$num"
}
println(showStudentInfo("Tom", getId))
输出:
Tom's id is 300027200012121001
其实这个写法非常的奇怪。声明一个函数然后又去调用,那干嘛不直接写一个函数呢?其实,上面的写法是不合理的,一般不会这么写,问题就出在var getId这个变量上,我们写了这个变量来引用函数类型,这是没有必要的,因为我们用函数类型的目的就是为了写匿名函数,取名字完全是多此一举。可以简化写成下面的样子。
println(showStudentInfo("Tom", { code, birth, num ->
"$code$birth$num"
}))
这样看起来就是非常简洁了。而且,kotlin有规定,如果只有一个函数类型,或者函数类型是最后一个,()可以省略。
函数类型是最后一个的情况:
println(showStudentInfo("Tom") { code, birth, num ->
"$code$birth$num"
})
只有一个函数类型做参数的时候
println(showStudentInfo { code, birth, num ->
"$code$birth$num"
})
这种写法一定要掌握,因为这个写法在kotlin里面是非常常见的。
这种写法一定要掌握,因为这个写法在kotlin里面是非常常见的。
这种写法一定要掌握,因为这个写法在kotlin里面是非常常见的。
内联函数的主要用途就是为匿名函数提高性能。在调用下面的有函数类型做为参数的方法时,会使用到匿名内部类。第二个参数要求我们传入匿名内部类,对于编译器来说,匿名内部类的创建和普通类是一样的,但既然是匿名的,效率应该要更高写,如果也是和普通类一样创建,效率就比较低了。内联函数就是为了解决这个性能问题,那么是怎么解决的呢?答案是通过宏替换,如果你学过C语言,你就知道C语言的宏替换,内联函数也是一样的,通过宏替换,我们直接把匿名内部类的代码直接复制到调用的函数里面,这样就不需要创建类了,不需要创建类当然性能就提高了。
private fun showStudentInfo(name: String, getId: (Int,Int,Int) -> String): String {
return xxx
}
使用方法就是直接添加一个inline关键字就可以了。
private inline fun showStudentInfo(name: String, getId: (Int,Int,Int) -> String): String {
return xxx
}
在调用含有函数类型的方法时,不光可以传入匿名内部类,也可以传通常的方法,这时候就需要用到函数引用。
例如下面的代码,foo方法的参数列表和showStudentInfo里面的getId函数类型的参数列表是一样的,这个时候可以把foo直接传给showStudentInfo。使用方法就是在::加普通函数名称。
private fun showStudentInfo( name:String, getId: (Int,Int,Int) -> String): String {
//必须用大括号
return "$name's id is ${getId(300027,20001212,1001)}"
}
private fun foo( a:Int,b:Int,c:Int ): String {
return "$a$b$c"
}
println(showStudentInfo("Tom", ::foo))
输出:
id is 300027200012121001
简单来说,就是一个函数返回另一个函数。什么?这有什么意义?如果有多个函数进行嵌套调用,那么就会形成函数之间的层层包含关系。这样的好处就是子函数可以共享父函数的变量,这种写法在脚本语言中是非常常见的,例如JavaScript。这样做的原因是脚本语言存在一个很大的问题,就是即使在不同的文件里面定义相同的变量名也会报错。因为脚本语言并没有像java这样有package和class的概念。kotlin也可以做为脚本语言。我们只能举个简单的例子来说明一下她的形式,理解的比较深还是需要大量的实践的。
看下面的代码,返回值是一个函数类型,传入一个String返回String。
private fun foo(a:Int):(String)->String{
return {
"$it"
}
}
在main函数中执行,返回函数类型的变量bar,可以调用,传入"abc"返回"abc"
var bar = foo(1)
println(bar.invoke("abc"))
输出:
abc
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景 最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。 在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记
目录H2数据库入门以及实际开发时的使用1.H2数据库的初识1.1H2数据库介绍1.2为什么要使用嵌入式数据库?1.3嵌入式数据库对比1.3.1性能对比1.4技术选型思考2.H2数据库实战2.1H2数据库下载搭建以及部署2.1.1H2数据库的下载2.1.2数据库启动2.1.2.1windows系统可以在bin目录下执行h2.bat2.1.2.2同理可以通过cmd直接使用命令进行启动:2.1.2.3启动后控制台页面:2.1.3spring整合H2数据库2.1.3.1引入依赖文件2.1.4数据库通过file模式实际保存数据的位置2.2H2数据库操作2.2.1Mysql兼容模式2.2.2Mysql模式