Kotlin语法糖--基础
不管你学习什么语言,开篇都是介绍基本类型,然后就是诸如控制流这种入门语法,随后就是对象、函数的使用,最后就是此语言的高级语法了。所以我们也按照这个流程,今天先介绍些简单的知识
本篇文章涉及到的代码已经提交到Github
-
基本类型
其实Kotlin中所有东西都是对象,这跟Java有点区别
-
数字
Kotlin对数字的处理在某种程度上接近Java,但是并不完全相同,比如Java可以将int隐式转换为long,这点Kotlin做不到。
Kotlin提供如下几种类型来表示数字
Type | Bit width |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
-
数值常量字面值
Kotlin支持二进制、十进制、十六进制,不支持八进制。这里还有几点要注意下:
(1) Long类型要在最后加“L”进行标记,比如100L
(2) 有浮点数默认都为Double,如果你想用Float来表示,那么就要在最后加“F”进行标记,例如100f
-
数值常量字面值中的下划线
这个一般体现在可读性上,比如你说说看100000是多少?在Java中你要从个十百千万的一个个点才知道,但是Kotlin就不同了,看代码
val a: Int=10000
val b: Int=10_000
println(a== b) // 返回true
-
装箱与拆箱
刚说了Kotlin中所有东西都是对象,而Java则是将数字存储为JVM的原生类型。所以Kotlin装箱之后,同一性不会被保留,但是保留了相等性。来看看代码吧
val boxA: Int? = a
var anotherBoxA: Int? = a
println(boxA == anotherBoxA)
println(boxA === anotherBoxA)
运行结果
-
显式转换
Kotlin里较小类型数不是较大类型数的子类型,所以不能直接隐式转换,并且代码也编译不过去
val a: Int=10000
val c: Long = a // 无法编译通过
我们可以通过显式的来进行转换
val c: Long = a.toLong()
每个数字类型支持如下的转换:
(1) toByte()
(2) toShort()
(3) toInt()
(4) toLong()
(5) toFloat()
(6) toDouble()
(7) toChar()
-
字符
字符要用Char类型表示,不能直接当数字使用。字符字面值用单引号括起来,比如'a'。特殊字符可以用反斜杠转义,支持如下几个转义序列\t、\b、\n、\r、\'、 \"、\\和$,其他编码类型要使用Unicode转义序列语法,比如'\uFF00'
-
布尔
两个值true和false
-
数组
数组在Kotlin中使用Array类来表示
我们一般使用arrayOf来创建一个数组并将元素传递给它
var array: Array<String> = arrayOf("1", "2", "3")
或者通过arrayOfNulls创建一个指定数量并且元素都为空的数组
var array1 = arrayOfNulls<String>(5)
甚至我们可以通过Array的构造方法创建一个基于索引来确定每个元素值的数组
var array2 = Array(5) {
"$it+Demo"
}
此处涉及到高阶函数部分,我们在后面会详细说明
数组可以通过[]运算符来调用成员函数get与set
var array: Array<String> = arrayOf("1", "2", "3")
array[0]
println(array[0])
array[1]="4"
println(array[1])
还有ByteArray、ShortArray、IntArray,这些跟Array并没有继承关系,但是它们都有同样的方法属性集
-
字符串
-
字符串字面值
Kotlin中的字符串分为转义字符串以及原生字符串。
转义字符串跟Java的差不多,来看看
val text1="Hello \n"
原生字符串使用三个引号(""")分解符括起来,内部没有转义并且可以包含换行和任何其他字符
var text= """
|ABC""
|DEF
|GHI
"""
println(text.trimMargin())
运行结果
默认是使用"|"作为边界前缀,你也可以选择其他字符作为参数传入
-
字符串模板
字符串可以包含模板表达式,即一些小段代码,并求值把结果合并到字符串中。模板表达式以美元符号$开头
var text="World"
val text12="Hello $text"
运行结果
除此之外,他还可以将表达式通过花括号括起来进行结果显示
println("1+2=${1+2}")
运行结果
最后一点,原生字符串中如果想实现转义功能,也可以通过字符串模板去实现
var text= """
|ABC""
|1+2=${'\n'}
|DEF
|GHI
"""
println(text.trimMargin())
运行结果
-
包
Kotlin中这部分跟Java还是差不多的
我现在同时定义2个类
目录结构
ClassA与ClassB基本上都是相同的,他们都有一个相同的类名字,叫APP
名字相同的类
好了我们现在要同时使用这2个类了
val appa: APP = APP()
val appb: APP = APP()
这样肯定不行的,这个谁不知道啊
要是在Java里面,肯定有一个类的变量类型是全路径显示的,就像这样
APP app=new APP();
com.renyu.kotlin.chapter2.b.APP app1=new com.renyu.kotlin.chapter2.b.APP();
这个实在是太长了是不是。Kotlin就有一个舒服的解决办法,用as关键字来重命名相同命名的冲突项
import com.renyu.kotlin.chapter2.b.APP as BAPP
import com.renyu.kotlin.chapter2.a.APP
这样呢,b包中的APP类就可以通过BAPP来声明了
val appa: APP = APP()
println(appa.value)
val appb: BAPP = BAPP()
println(appb.value)
-
控制流
-
if表达式
这个在之前的文章中已经提及了很多,这里也是说重点。除了可以像Java一样作为语句来使用之外,如果你将其作为表达式来使用,必须要有else分支
var a1=10
var b2=20
var maxValue: Int = if (a1>b2) {
println(a1)
a1
} else {
println(b2)
b2
}
println(maxValue)
最后的表达式就是该语句的值
-
when表达式
when取代了switch语句,但是它并不仅仅是替代作用,在使用上when表达式还进行了扩展升级。常用的形式有三种:常量结构、in结构、表达式结构。
when语句与switch语句的区别是,如果符合判断中的任意一条表达式,则在执行表达式对应的语句体之后,直接跳出整个when逻辑,我们不需要手动的break。
如果when语句作为一个表达式来使用,必须要有else分支,除非编译器检测出来你把所有可能发生的情况都考虑到了
先看下典型使用
fun getValue(value: Int) : String {
return when(value) {
1 -> "a"
2 -> "b"
else -> "other"
}
}
如果我们希望一个逻辑值value能够对应多个常量值,则我们就必须使用in结构。其操作,与常量结构的when语句类似,即将满足一个条件的多个常量值使用 “,” 隔开如果想合并多个分支,那么用逗号分隔即可
fun getValue(value: Int) : String {
return when(value) {
1,3 -> "a"
2 -> "b"
else -> "other"
}
}
同样可以使用任意表达式作为分支条件
fun getValue(value: Int) : String {
return when(value) {
1,3 -> "a"
2 -> "b"
"5".toInt() -> "e"
else -> "other"
}
}
当然,我们也可以将多个表达式对应一个判断同时使用,只需要在两个表达式之间增加“,”符号
最后,我们可以用when来取代if-else if链,我们来改写一下上文的if表达式的例子
var maxValue1: Int = when {
(a1>b2) -> {
a1
} else -> {
b2
}
}
println(maxValue1)
-
for循环
不多说了
-
while循环
不多说了
-
返回和跳转
跟Java一样,也是break、continue、return,对比一下Java的写法,应该就能清楚明白了
-
break,continue标签
String[] arrays={"1", "2", "3", "4", "5"};
outer:
for (String array : arrays) {
System.out.println("1. "+array);
for (int i=0;i<3;i++) {
System.out.println("1. "+i);
if (i==2) {
break outer;
}
}
}
var array3: Array<String> = arrayOf("1", "2", "3", "4", "5")
loop@ for (s in array3) {
println("1. $s")
for (i in 0..3) {
println("2. $i")
if (i==2) {
break@loop
}
}
}
这里我们可以通过标签来控制返回和跳转流程,标签的格式为标识符后跟@符号
-
标签处返回
来看一下这几行代码
fun foo() {
var array: Array<String> = arrayOf("1", "2", "3", "4", "5")
array.forEach {
if (it == "2") {
return
}
println("$it")
}
println("结束")
}
一旦执行到了这个return,那么我们就将从foo中返回了。我现在想仅从forEach中跳出当前循环,那就必须要给他加标签来限制return了
fun foo() {
var array: Array<String> = arrayOf("1", "2", "3", "4", "5")
array.forEach a@{
if (it == "2") {
return@a
}
println("$it")
}
println("结束")
}
return@标签跳出当前Lambda表达式
通常情况下隐式标签更为方便,该标签与lambda的函数同名,即
fun foo() {
var array: Array<String> = arrayOf("1", "2", "3", "4", "5")
array.forEach {
if (it == "2") {
return@forEach
}
println("$it")
}
println("结束")
}
入门语法就讲到这里了,下回我们来说说类和对象