Kotlin基础1——变量常量与类型、条件语句、函数

一.变量常量与类型

1.声明变量

image.png

2.Kotlin内置数据类型

image.png

3.只读变量

var:如果要声明可修改变量,使用var修饰符;
val:如果要声明只读变量,使用val修饰符(类似于Java的final);

image.png

以上代码中,hello可修改,name不可修改,如果重新给name赋值则代码会报错;

4.类型推断

类型推断:对于已声明并赋值的变量,可以省略类型定义。

image.png

你可以直接声明变量名而不需要显示的声明变量类型,Kotlin强大的编译器会自动根据“=”右边的值的类型来自动推断出你所声明的变量的类型;

5.编译时常量

编译时常量只能在函数之外定义,因为编译时常量必须在编译时赋值,而函数都是在运行时才调用,函数内的变量也是在运行时赋值,编译时常量要在这些变量赋值前就已存在。

image.png

注:编译时常量只能是常见的基本数据类型:String、Int、Double、Float、Long、Short、Byte、Char、Boolean。

6.查看Kotlin字节码

查看Kotlin编译之后的字节码,有助于我们深入理解Kotlin语言。
查看方式:
(1)Shift键两次,输入Show kotlin
(2)Tools->Kotlin->Show Kotlin Bytecode

image.png

7.Kotlin的引用类型与基本数据类型

(1)Java中有两种数据类型:”引用类型“与”基本数据类型“。
(2)Kotlin只提供了”引用类型“这一种数据类型,出于更高性能的需要,kotlin编译器会在Java字节码中改用基本数据类型。

二.条件语句

1.表达式

(1)if/else if表达式
(2)range表达式
* in A..B,in关键字用来检查某个值是否在指定范围之内。

image.png

执行结果:少儿

(3)when表达式
* 允许你编写条件式,在某个条件满足时执行对应的代码
* 只要代码包含else if分支,都建议改用when表达式

image.png

执行结果:少儿

2.String模版

(1)模版支持在字符串的引号内放入变量值

image.png

执行结果:Jack love Rose

(2)还支持字符串里计算表达式的值并插入结果,添加在${}中的任何表达式都会作为字符串的一部分求值

image.png

执行结果:Answer is 对不起

三.函数

1.函数头

image.png

2.函数参数

(1)默认值参
* 如果不打算传入值参,可以预先给参数指定默认值

image.png

(2)具名函数参数
* 如果使用命名值参,就可以不用管值参的顺序

image.png

执行结果:Jack 20

3.Unit函数

不是所有函数都有返回值,Kotlin中没有返回值的函数叫Unit函数,也就是说它们的返回类型是Unit。在Kotlin之前,函数不返回任何东西用void描述,意思是“没有返回类型,不会带来什么,忽略它”,也就是说如果函数不返回任何东西,就忽略类型。但是void这种解决方案无法解释现代语言的一个重要特征——范型。

3.Nothing类型

TODO函数的任务就是抛出异常,就是永远别指望它运行成功,返回Noting类型

image.png

执行结果:
image.png

4.反引号(``)中的函数名

(1)Kotlin可以使用空格和特殊字符对函数命名,不过函数名要用一对反引号括起来。

错误示范:
image.png

运行会报错

正确示范:
image.png

运行不会报错,且运行结果为:123

(2)为了支持Kotlin和Java互操作,而Kotlin和Java各自却有着不同的保留关键字,不能作为函数名,使用反引号括住函数名就能避免这种冲突

错误示范:
image.png

“is”为Kotlin的关键字,函数命名使用“is”会报错

正确示范:
image.png

如果有个Java类中的方法名叫“is”,在Kotlin中调用该方法也要使用反引号

image.png

5.匿名函数

(1)定义时不取名字的函数我们称之为匿名函数,匿名函数通常整体传递给其它函数或者从其他函数返回。
(2)匿名函数对Kotlin来说很重要,有了它,我们能够根据需要制定特殊规则,轻松定制标准库里的内置函数。

image.png

执行结果:
11
4
count函数为Kotlin标准库的内置函数,用来获取字符串长度。

6.函数类型与函数类型参数

(1)匿名函数也有类型,匿名函数可以当作变量赋值给函数类型的变量,就像其他变量一样,匿名函数就可以在函数间传递了。
(2)和具名函数不一样,除了极少数情况外,匿名函数不需要return关键字来返回数据,匿名函数会隐式或自动返回函数体最后一行语句的结果。
(3)和具名函数一样,匿名函数可以不带参数,也可以带一个或多个任意类型的参数,需要带参数时,参数的类型放在匿名函数的类型定义中,参数名则放在函数定义中

image.png

执行结果:Jack, Happy New Year

7.it关键字

定义只有一个参数的匿名函数时,可以使用it关键字来表示参数名。但你需要传入两个值参时,it关键字就不能用了。

image.png

其中“Jack”传给匿名函数,匿名函数没有显示的声明值参,而是默认的使用了it来作为接受参数

8.函数类型推断

(1)定义一个变量时,如果已把匿名函数作为变量赋值给它,就不需要显示指明变量类型了。

image.png

(2)类型推断也支持带参数的匿名函数,但为了帮助编译器更准确地推断变量类型,匿名函数的参数名和参数类型必须有

image.png

9.lambda

我们将匿名函数称为lambda,将它的定义称为lambda表达式,它返回的数据称为lambda结果。

10.定义参数是函数类型的函数

顾名思义就是函数的参数是另外一个函数

image.png

其中“showOnBoard”第二个参数"getDiscountWords"是一个函数类型的参数(该函数有两个参数,第一个是String类型,第二个是Int类型,返回值是String)

11简略写法

如果一个函数的lambda参数排在最后,或者是唯一的参数,那么括住lambda值参的一对圆括号就可以省略。

image.png
image.png

12.函数内联

lambda可以让你更灵活地编写应用,但是灵活也是要付出代价的。

在JVM上,你定义的lambda会以对象实例的形式存在,JVM会为所有同lambda打交道的变量分配内存,这就产生了内存开销。更糟糕的是,lambda的内存开销会带来严重的性能问题。幸运的是Kotlin有一种优化机制——内联,内联函数的用法非常简单,只需要在定义函数时在fun前加上inline关键字的声明即可。

有了内联,JVM就不需要使用lambda对象实例了,从而避免了变量内存分配。哪里需要使用lambda,编译器就会将函数体复制粘贴到哪里。

使用lambda的递归函数无法内联,因为会导致复制粘贴无限循环,编译会发出警告。

image.png

以上代码转成Java代码如下:

image.png

可以看到之前的lambda表达式变成了Function接口的实现类(定义的lambda会以对象实例的形式存在)

使用内联函数:

image.png

以上代码转成Java代码如下:

image.png

可以看到,Kotlin编译器将内联函数中的代码在编译时自动替换到调用它的地方(类似C/C++中的宏定义),这样JVM就不需要使用lambda对象实例了,从而避免了变量内存分配。

13.函数引用

要把函数作为参数传给其它函数使用,除了传lambda表达式,Kotlin还提供了其它方法——传递函数引用,函数引用可以把一个具名函数转换成一个值参,使用lambda表达式的地方都可以使用函数引用。

image.png

执行结果:
image.png

14.函数类型作为返回类型

函数类型也是有效的返回类型,也就是说可以定义一个能返回函数的函数。

image.png

15.闭包

(1)在Kotlin中,匿名函数能修改并引用定义在自己的作用域之外的变量,匿名函数引用着定义自身的函数里的变量,Kotlin中的lambda就是闭包。

image.png
image.png

(2)能接收函数或者返回函数的函数又叫做高级函数,高级函数广泛应用于函数式编程当中。

16.lambda与匿名内部类

为什么要在代码中使用函数类型?
函数类型能方开发者少写模式化代码,写出更灵活的代码。Java8支持面向对象编程和lambda表达式,但不支持将函数作为参数传给另一个函数或变量,不过Java的替代方案是匿名内部类。

你可能感兴趣的:(Kotlin基础1——变量常量与类型、条件语句、函数)