文章目录
1、基本类型
kotlin 的基本类型主要包括:
- 数字
- 字符
- 布尔
- 数组
看起来与Java差不多,但是有一个根本的区别,kotlin 中的基本类型也都是面向对象的,而Java中的基本类型还区分包装类型和原始类型。
1.1 数字
Kotlin 对数字的处理与Java类似,但也有很大差异。 然而对于数字类型, Kotlin 却不兼容 Java 中的类型 例如,你不能这样在 Kotlin中声明和初始化一个 Java 中的整型类型:
var a : Integer= Intege r(3)
同样,在 Kotlin 中,不能声明 Java 中其他的基本数字类型,例如:
var b : Long = Long ()
之所以会这样,是因为 Kotlin 有自己的一套基本类型,并且有重名的类,例如Kotlin 的长整型类型为 Long ,这与 Java 的长整型类型名称相同。
kotlin 一共提供了6种类型
Double、Float、Long、Int、Short、Byte
var c='a'
var a = c as Int
val b = 1
1.1.1 字面常量
字面常量就是直接在源程序中写一个数字,编译器在进行编译时,会识别的这种数字符号。
kotlin 所支持的数字标识符包括以下几种:
- 普通十进制 不需要添加任何标识符,如val a=123
- Long 类型 用L标识 如:12L
- 十六进制 用0X 开头 如val d=0x0BAF
- 二进制 用0b开头 val c=0b1011001010
- 浮点类型 默认double 如 12.34、34.567
- Float类型 用 f 或 F 标记 12.13f
1.1.2 显式转换
每一种数字类型都支持以下方法:
• toByte(): Byte
• toShort(): Short
• tolnt(): Int
• toLong(): Long
• toFloat(): Float
• toDouble(): Double
• toChar(): Char
有了这些接口,你可以进行任意两种数字类型之间的转换 例如可以这样:
var a:Int = 3
va r b:Long = a.toLong()
1.2 字符串
Ko ti In 中的字符串使用 String 类型表示,不过这种类型也是 Kotlin 内置的类型,并不是 Java 中的字符串类型。
与Java 中的字符串一样, Koti in 的字符串也是不可变的一一不能被继承,值不能被修改。因此在对字符串执行拼接操作时需要考虑性能问题Kotlin 中,关于字符串有一个很贴心的功能,那就是模板表达式。
va l i = 3
val s = " i = $i"
val ss = " i =${ i + 5 )"
println (” $s” )
2 变量与常量
2.1 常量
所谓常
就是其值不能在运行期被修改的变量 Kotlin 中声明 个常量很简单,使用 val
键字 可,如下所示
val a : Int = 3
并非加了val 关键字的变更才会被认为是常量,还有一类隐式的常量,那就是函数的入参。
fun add(a: Int) {
val b =a+3
}
2.2 属性包装
kotlin 相比 Java 的一个重大改进就是属性的自动封装。
3 函数
3.1 函数声明
kotlin 函数声明使用fun 关键字声明
fun add(a: Int) {
val b =a+3
}
如果kotlin 函数没有返回值,则可不声明返回值,不需要像Java 那样使用void关键字。
单表达式
fun aaa(a: Int, b: Int): Int = a + b
还可以
fun aaa(a: Int, b: Int) = a + b
返回值类型
与其它语言一样,允许函数没有返回值,其类型是 kotlin.Unit
函数类型
函数类型非常丰富,大致有以下
- 顶级函数
就是直接声明在源程序文件中的函数,而不是被封装有类型内部。
class Anima{
override fun toString() ="anima"
}
// 顶级函数与类型声明平级
fun eat(anima: Anima){
println("animal eat")
}
- 类成员函数
声明在类型内部的函数
class Anima{
override fun toString() ="anima"
...
//类成员函数
fun eat(anima: Anima){
println("animal eat")
}
....
}
- 对象函数
声明在对象中的函数 - 本地函数
本地函数是一种类型特殊的函数,这类函数声明在其它函数内部。
函数参数
fun main(args: Array<String>) {
println("Hello word")
val d = 0x0BAF
val c = 0b1011001010
/*
fun add(a: Int) {
val b =a+3
}
*/
......
// 也可以是包含多个参数,其中一个是不定长参数
fun add(a: Int, vararg t : Int) {
println("t.size=${t.size}")
if (t.size > 0) {
var sum: Int = 0
for (num in t) {
sum = sum + num
println("sum= ${sum}")
}
}
}
3.2 闭包
就是局部函数,局部函数也可以读取其它函数内部的数据。
class Closure{
var count = 0
fun foo() {
var a = 1
//闭包
fun local() {
a++
count++
//局部函数访问外部宿主资源
println("a=${a},count=${count}")
}
}
}
3.3 lambda 表达式
就是匿名函数
匿名函数主要用在下面两种地方:
- 函数入参
- 函数返回值
- 函数类型
使用格式如下:
var variable:(argType[,...]) -> returnType
声明一个Int 类型的变更
var int : Int
将这两种对比,本质上是一样的,唯一不同是变量类型。
再如
var addFun : (Int,Int) -> Int
fun add(a:Int,b:Int):Int{
return a+b
}
- 函数实例化与lambda表达式
普通变量直接调用构造函数便能完成实例化,而函数类型则需要借助于lambda表达式才能完成实例化。
var addFun: (Int,Int) -> Int = { a, b -> a + b }
- 函数类型返回
函数类型实例化的函数体内部,不能使用return 关键字进行返回。 - 函数类型赋值与调用
函数类型并不是唯一的,入参不同,返回值类型不同,则函数类型便有差别。 - 函数类型传递与高阶函数
既然函数类型变量具有普通变量的属性,自然也可以作为参数传递给其他函数能够接受函数类型的变量作为人参,或者返回一个函数类型的函数,专业上称之为“高阶函数”。
可以当作函数进行调用,在调用这种类型的变量时,只需在变量名后面添加括号,并传递对应的实参。
下面这种文法定义了 个接受函数类型作为入参的高阶函数:
fun advanceFun(a: Int, funcType: (Int, Int) -> Int) {
funcType(a, 86)
这里声明的 advanceFun()函数,其第 个人参 funcType 便是 个函数类型 ,其函数类型表明这是一个包含两个 Int 型入参、返回 Int 类型的函数.
下面这种文法定义了一个返回函数类型的高阶函数:
fun advanceFun(a : Int): (Int, Int) -> Int{
return {
a, b ->
a + b
}
}
fun main(args: Array<String>) {
/*声明高阶函数*/
fun advanceFun(a : Int,funcType : (Int,Int) -> Int){
funcType(a,3)
}
/*声明一个函数变量*/
var funcType:(Int,Int) ->Int ={
a,b ->
a+b
}
/*调用高阶函数*/
advanceFun(98, funcType)
}
-
高阶函数简写形式
高阶函数不仅声明文法稍显复杂,毕竟突破了大家习以为常的形式,而且在调
时即时 明和使用函数类型变量的文法也会使程序看起来复杂度骤然大增( 主要是
lambda 表达式的结构比较复杂) 为了简化, lambda 文法规定:
如果一个高阶函数的最 个人参是函数类型,则在调用该高阶函数时,可以该入参从人参列表中移到入参列表外面,并使用花括号括起来。
如果高阶函数仅包含 个人参,并且这个人参就是高阶函数类型, 那么使用简化调用形式之后,其入参列表可以为空。 -
it
当一个函数类型只包含一个入参时,高阶函数可以简化成“it”关键字。 -
闭包的连续调用
闭包实现的前提是函数必须返回一个函数类型的结果值,也就是高阶函数。而返回的函数类型的变量,可以是高阶函数内部的局部函数。 -
内联函数
就是将函数体直接移到调用者函数内部来执行。