189 8069 5689

kotlin基础——>基本数据类型、控制流、返回和跳转-创新互联

1.对于数字的定义,支持java 8的下划线分割的方式kotlin基础——>基本
数据类型、控制流、返回和跳转 val a = 1_2_3 与 val a = 123 是相同的

2.如果要指定数字类型有两种方式

在宁陕等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站建设、成都网站建设 网站设计制作按需求定制网站,公司网站建设,企业网站建设,成都品牌网站建设,成都全网营销推广,外贸营销网站建设,宁陕网站建设费用合理。val a : Float = 1 或者 val a = 1f

3.kotlin没有隐式拓宽转换

val i = 1 val d = 1.1 val f = 1.1f printDouble(d) printDouble(i) // 错误:类型不匹配 printDouble(f) // 错误:类型不匹配

4.kotlin数字定义不支持八进制

十进制: 123 -- Long类型 123L 十六进制: 0x0f 二进制: 0b001

5.当采用可空的引用(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 => Long

7.运算时,整数计算只会得到整数,如果需要返回浮点,需要其中一个进行显式转换

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..b

10.字符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 赋值给Array,以防止可能的运行时失败(但是你可以使用 Array,参⻅类型投影)。

// 创建一个 Array 初始化为 ["0", "1", "4", "9", "16"] val asc = Array(5) { i -> (i * i).toString() } asc.forEach { println(it) }

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) 注解标注声明,
要么将 -Xopt-in=kotlin.ExperimentalUnsignedTypes 传给编译器。

 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() {
   listOf(1, 2, 3, 4, 5).forEach {     if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调用者,即 forEach 循环     print(it)    }

   print(" done with implicit label")

 }

 //或者用一个匿名函数替代lambda表达式,这样return返回的是匿名函数自身

 fun foo() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {        if (value == 3) return // 局部返回到匿名函数的调用者,即 forEach 循环        print(value)     })     print(" done with anonymous function")  }

 24.1 当要返回一个回值的时候,解析器优先选用标签限制的return,例如:

return@a 1//意为“返回 1 到 @a ”,而不是“返回一个标签标注的表达式 (@a 1) ”

本文题目:kotlin基础——>基本数据类型、控制流、返回和跳转-创新互联
URL地址:http://cdxtjz.cn/article/dhoopd.html

其他资讯