2.如果要指定数字类型有两种方式
在宁陕等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站建设、成都网站建设 网站设计制作按需求定制网站,公司网站建设,企业网站建设,成都品牌网站建设,成都全网营销推广,外贸营销网站建设,宁陕网站建设费用合理。val a : Float = 1 或者 val a = 1f3.kotlin没有隐式拓宽转换
val i = 1 val d = 1.1 val f = 1.1f printDouble(d) printDouble(i) // 错误:类型不匹配 printDouble(f) // 错误:类型不匹配4.kotlin数字定义不支持八进制
十进制: 123 -- Long类型 123L 十六进制: 0x0f 二进制: 0b0015.当采用可空的引用(Int?)或泛型,后者情况会把数字装箱,装箱的数字保留相等性,但不一定保留同一性
val a: Int = 10000 println(a === a) // 输出“true” val boxedA: Int? = a val anotherBoxedA: Int? = a println(boxedA === anotherBoxedA) // !!!输出“false”!!! 但保留相等性 val a: Int = 10000 println(a == a) // 输出“true” val boxedA: Int? = a val anotherBoxedA: Int? = a println(boxedA == anotherBoxedA) // 输出“true”6.显示转换,现在无法直接用long类型接收一个int类型的数字,在早起版本会把int类型装箱变为Long类型,后续版本在编译期就会报错,无法通过默认方式的编译成功
// 假想的代码,实际上并不能编译: val a: Int? = 1 // 一个装箱的 Int (java.lang.Integer) val b: Long? = a // 隐式转换产生一个装箱的 Long (java.lang.Long) print(b == a) // 惊!这将输出“false”鉴于 Long 的 equals() 会检测另一个是否也为 Long //以下的方式也是错的 val b: Byte = 1 // OK, 字面值是静态检测的 val i: Int = b // 错误 但是可以通过显式转换 val i: Int = b.toInt() // OK:显式拓宽 可以使用以下的方式 — toByte(): Byte — toShort(): Short — toInt(): Int — toLong(): Long — toFloat(): Float — toDouble(): Double — toChar(): Char 注意: val l = 1L + 3 // Long + Int => Long7.运算时,整数计算只会得到整数,如果需要返回浮点,需要其中一个进行显式转换
val x = 5 / 2.toDouble() println(x == 2.5)8.位运算,对于位运算,没有特殊字符来表示,而只可用中缀方式调用具名函数
val x = (1 shl 2) and 0x000FF000 这是完整的位运算列表(只用于 Int 与 Long): — shl(bits) ‒ 有符号左移 — shr(bits) ‒ 有符号右移 — ushr(bits) ‒ 无符号右移 — and(bits) ‒ 位与 — or(bits) ‒ 位或 — xor(bits) ‒ 位异或 — inv()‒位非9.区间比较
区间实例以及区间检测:a..b、x in a..b、x !in a..b10.字符Char,不能直接作为数字,可以显式转换
字符字面值用单引号括起来: '1' 。特殊字符可以用反斜杠转义。支持这几个转义序列: 、 、 、 、' 、" 、\ 与 $ 。编码其他字符要用 Unicode 转义序列语法:'uFF00' fun decimalDigitValue(c: Char): Int { if (c !in '0'..'9') throw IllegalArgumentException("Out of range") return c.toInt() - '0'.toInt() // 显式转换为数字 }11.数组,在kotlin中使用Array类来表示,在kotlin中是不型变的(invariant)。这意味着 Kotlin 不让我们把 Array
12.原生类型数组
val x: IntArray = intArrayOf(1, 2, 3) x[0] = x[1] + x[2] // 大小为 5、值为 [0, 0, 0, 0, 0] 的整型数组 val arr = IntArray(5) // 例如:用常量初始化数组中的值 // 大小为 5、值为 [42, 42, 42, 42, 42] 的整型数组 val arr = IntArray(5) { 42 } // 例如:使用 lambda 表达式初始化数组中的值 // 大小为 5、值为 [0, 1, 2, 3, 4] 的整型数组(值初始化为其索引值) var arr = IntArray(5) { it * 1 }13.无符号整型(kotlin 1.3起才可用)
val a :UByte = 1u val b: Byte = a.toByte() 注意:将类型从无符号类型更改为对应的有符号类型(反之亦然)是二进制不兼容变更14.特化的类
与原生类型相同,每个无符号类型都有相应的为该类型特化的表示数组的类型: — kotlin.UByteArray : 无符号字节数组 — kotlin.UShortArray : 无符号短整型数组 — kotlin.UIntArray : 无符号整型数组 — kotlin.ULongArray : 无符号⻓整型数组 与有符号整型数组一样,它们提供了类似于 Array 类的 API 而没有装箱开销。 此外,区间与数列也支持 UInt 与 ULong(通过这些类 kotlin.ranges.UIntRange 、 kotlin.ranges.UIntProgression 、kotlin.ranges.ULongRange 、 kotlin.ranges.ULongProgression )15.无符号是实验性的,如果要使用需要加入声明
— 如需传播实验性,请以 @ExperimentalUnsignedTypes 标注使用了无符号整型的声明。 — 如需选择加入而不传播实验性,要么使用 @OptIn(ExperimentalUnsignedTypes::class) 注解标注声明,16.字符串关于"""(原始字符串)以及trimMargin()的使用
val text = """ |Tell me and I > forget. |Teach me and I > remember. |Involve me and > I learn. |(Benjamin Franklin) """ println(text) 输出结果(上下的换行,和前面的空格都是): |Tell me and I > forget. |Teach me and I > remember. |Involve me and > I learn. |(Benjamin Franklin) val text = """ |Tell me and I > forget. |Teach me and I > remember. |Involve me and > I learn. |(Benjamin Franklin) """.trimMargin() println(text) 输出结果: Tell me and I > forget. Teach me and I > remember. Involve me and > I learn. (Benjamin Franklin) 注意:trimMargin() 函数为去除前导空格,默认以 | 作为边界前缀,所以等同于trimMargin("|") ,边界前缀可以自己定义17.字符串模版,可以直接使用 $ 符号
val i = 10 println("i = $i") // 输出“i = 10” val s = "abc" println("$s.length is ${s.length}") // 输出“abc.length is 3”18.包导入,于java基本相同,对于出现名字冲突的可以使用as另外定义一个名字来取消冲突和歧义
import org.example.Message // Message 可访问 import org.test.Message as testMessage // testMessage 代表“org.test.Message”19.在kotilin中if为一个表达式,可以返回一个值,也就是说对于三元运算符的写法,也可以用if替代,当然如果使用if作为表达式,那么必须要有else分支
1 //传统用法 2 var max: Int
3 if (a > b) {
4 max = a
5 } else {
6 max = b
7 }
8
9
10 // 作为表达式11 val max = if (a > b) a else b
12
13 //或者写作14 val max = if (a > b) {
15 print("Choose a")
16 a
17 } else {
18 print("Choose b")
19 b
20 }
20.when取代了之前的switch,同样如果用于作为表达式,必须要有else分支,以下为when的几种写法
1 when (x) {
2 1 -> print("x == 1")
3 2 -> print("x == 2")
4 else -> { // 注意这个块 5 print("x is neither 1 nor 2")
6 }
7 }
8
9
10 //多条件相同处理时,用 , 分割11 when (x) {
12 0, 1 -> print("x == 0 or x == 1")
13 else -> print("otherwise")
14 }
15
16 //可以用任意表达式作为分支,而不仅仅是常量17 when (x) {
18 parseInt(s) -> print("s encodes x")
19 else -> print("s does not encode x")
20 }
21
22 //也可以检测一个值在(in)或者不在(!in)一个区间或者集合中23 when (x) {
24 in 1..10 -> print("x is in the range")
25 in validNumbers -> print("x is valid")
26 !in 10..20 -> print("x is outside the range")
27 else -> print("none of the above")
28 }
29
30 //另一种可能性是检测一个值是(is)或者不是(!is)一个特定类型的值。注意:由于智能转换,你可以访 问该类型的方法与属性而无需任何额外的检测。31
32 fun hasPrefix(x: Any) = when(x) {
33 is String -> x.startsWith("prefix")
34 else -> false35 }
36
37 //when 也可以用来取代 if-else if链38 when {
39 x.isOdd() -> print("x is odd")
40 y.isEven() -> print("y is even")
41 else -> print("x+y is even.")
42 }
43
44 //自kotlin 1.3起,可以使用以下语法将 when 的主语(subject,译注:指 when 所判断的表达式)捕获到 变量中:45
46 fun Request.getBody() =
47 when (val response = executeRequest()) {
48 is Success -> response.body
49 is HttpError -> throw HttpException(response.status)
50 }
51
52 注意:在 when 主语中引入的变量的作用域仅限于 when 主体。
21.for循环,可以对任何提供迭代器(iterator)的对象进行遍历,这相当于像 C# 这样的语言中的 foreach 循环
1 // 1. 基本语法 2 for (item in collection) print(item)
3
4 //2.循环体是一个代码块 5 for (item: Int in ints) {
6 // ...... 7 }
8
9 //说明:for 可以循环遍历任何提供了迭代器的对象。即:
10 // — 有一个成员函数或者扩展函数 iterator(),它的返回类型
11 // — 有一个成员函数或者扩展函数 next(),并且
12 // — 有一个成员函数或者扩展函数 hasNext() 返回 Boolean 。
13 // 这三个函数都需要标记为 operator
14
15 //3. 使用数字区间迭代16 for (i in 1..3) {
17 println(i)
18 }
19 for (i in 6 downTo 0 step 2) {
20 println(i)
21 }
22
23 // 说明:对区间或者数组的 for 循环会被编译为并不创建迭代器的基于索引的循环。
24
25 //4.如果想要通过索引遍历一个数组或者list,你可以这么做:26 for (i in array.indices) {
27 println(array[i])
28 }
29
30 //4.1 或者使用库函数 withIndex31 for ((index, value) in array.withIndex()) {
32 println("the element at $index is $value")
33 }
22.while循环,这个没什么变化,于java相同
while (x > 0) {
x--
}
do {
val y= retrieveData()
}while (y != null) // y 在此处可⻅
23.在kotlin中break和continue增加了指定标签的方式,类似于C的写法,标签的格式为 标识符后跟@符号,例如 abc@
loop@ for (i in 1..100) {
for (j in 1..100) {
if (......) break@loop
}
}
24.return也可以采用标签返回的方式,这种方式主要是为了更好的应用于lambda表达式中
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // 局部返回到该 lambda 表达式的调用者,即forEach 循环 print(it)
}
print(" done with explicit label")
}
//当然也可以使用隐式标签,该标签于接受该lambda的函数同名
fun foo() {print(" done with implicit label")
}
//或者用一个匿名函数替代lambda表达式,这样return返回的是匿名函数自身
fun foo() {24.1 当要返回一个回值的时候,解析器优先选用标签限制的return,例如:
return@a 1//意为“返回 1 到 @a ”,而不是“返回一个标签标注的表达式 (@a 1) ”