kotlin基础——>基本数据类型、控制流、返回和跳转
1.对于数字的定义,支持java 8的下划线分割的方式
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' 。特殊字符可以用反斜杠转义。支持这几个转义序列:\t 、 \b 、\n 、\r 、\' 、\" 、\\ 与 \$ 。编码其他字符要用 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<String> 赋值给Array<Any>,以防止可能的运行时失败(但是你可以使用 Array<out Any>,参⻅类型投影)。
// 创建一个 Array<String> 初始化为 ["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 -> false
35 }
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 或者使用库函数 withIndex
31 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的函数同名
listOf(1, 2, 3, 4, 5).forEach {
print(" done with implicit label")
}
//或者用一个匿名函数替代lambda表达式,这样return返回的是匿名函数自身
listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
24.1 当要返回一个回值的时候,解析器优先选用标签限制的return,例如:
return@a 1
//意为“返回 1 到 @a ”,而不是“返回一个标签标注的表达式 (@a 1) ”
kotlin基础——>基本数据类型、控制流、返回和跳转的更多相关文章
- Python 编程核心知识体系-基础|数据类型|控制流(一)
Python知识体系思维导图: 基础知识 数据类型 1.序列 2.字符串 3.列表和元组 4.字典和集合 循环 & 判断
- Go语言基础之数据类型
Go语言基础之数据类型 Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. ...
- C语言基础知识-数据类型
C语言基础知识-数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常量与变量 1>.关键字 C的关键字共有32个. >.数据类型关键字(12个) char,s ...
- JavaScript基础:数据类型的中的那些少见多怪
原文:JavaScript基础:数据类型的中的那些少见多怪 Javascript共有6种数据类型,其中包括3个基本数据类型(string,number,boolean).2个特殊数据类型(undefi ...
- js基础--javaScript数据类型你都弄明白了吗?绝对干货
欢迎访问我的个人博客:http://www.xiaolongwu.cn 数据类型的分类 JavaScript的数据类型分为两大类,基本数据类型和复杂数据类型. 基本数据类型:Null.Undefine ...
- 第二章:python基础,数据类型
"""第二章:python基础,数据类型2.1 变量及身份运算补充2.2 二进制数2.3 字符编码每8位所占的空间位一个比特,这是计算机中最小的表示单位.每8个比特组成一 ...
- C#基础 常用语&数据类型定义&类型转换
int temp = Console.Read(); Console.WriteLine(temp); Console.Read(); Console.Write(" ");直接 ...
- python基础一数据类型之字典
摘要: python基础一数据类型之一字典,这篇主要讲字典. 1,定义字典 2,字典的基础知识 3,字典的方法 1,定义字典 1,定义1个空字典 dict1 = {} 2,定义字典 dict1 = d ...
- Java基础-Java数据类型
Java基础-Java数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据类型的作用 数据类型就是一组值,以及这一组值上的操作,数据类型可以决定数据的存储方式,取值范围 ...
- Kotlin基础篇(一)
写在前面: 因为工作需要,目前转安卓开发,用的IDE是AS3.2版本,语言的话,用的是Kotlin.由于之前是做.NET的,没接触过这方面的东西,所以完全是小白一枚.所以想着开个博客,以此来记录自己的 ...
随机推荐
- 【Zookeeper】Re03 集群搭建
我这里采用的是模拟真实情况: 部署三台虚拟机Centos7 192.168.242.101 192.168.242.102 192.168.242.103 每台机器都安装Zookeeper且一致: / ...
- 【Spring-Security】Re14 Oauth2协议P4 整合SSO单点登陆
创建一个SSO单点登陆的客户端工程 需要的依赖和之前的项目基本一致: <?xml version="1.0" encoding="UTF-8"?> ...
- 【Layui】08 时间线 Timeline
文档地址: https://www.layui.com/demo/timeline.html 常规时间线: <ul class="layui-timeline"> &l ...
- 英语词汇:simplistic和simple区别
"Simplistic" 和 "simple" 都表示简单,但它们有不同的含义和语境: Simplistic: 含义: 过于简单化的,有贬义,表示忽略了复杂性或 ...
- 如何在 Ubuntu18.04 server 服务器版本的操作系统下 配置IP
如题,现有需求,为一个server版本的Ubuntu18.04配置 IP . 在网上查到了 Ubuntu18.04 桌面版本 的配置方法: https://www.cnblogs.com/ ...
- 再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(8) —— 2021年9月SOTA的TDL算法——《Optimistic Temporal Difference Learning for 2048》——完结篇
<2048>游戏在线试玩地址: https://play2048.co/ 如何解决<2048>游戏源于外网的一个讨论帖子,而这个帖子则是讨论如何解决该游戏的最早开始,可谓是&q ...
- 深入理解 PHP 高性能框架 Workerman 守护进程原理
大家好,我是码农先森. 守护进程顾名思义就是能够在后台一直运行的进程,不会霸占用户的会话终端,脱离了终端的控制.相信朋友们对这东西都不陌生了吧?如果连这个概念都还不能理解的话,建议回炉重造多看看 Li ...
- git push --recurse-submodules = on-demand 递归push
I have the following project structure: root-project | |-- A | | | |-- C | |-- B A和B是根项目的子模块. C又是项目A ...
- Camera | 12.瑞芯微摄像头自动焦距马达驱动移植
本为你主要讲解如何让摄像头ov13850支持自动对焦功能. 摄像头的对角主要通过VCM马达驱动芯片DW9714来实现的. 一.环境 soc : rk3568 board: EVB1-DDR4-V10 ...
- Lucas-Washburn + Cassie-Baxter
如果粉末间隙内壁的表面能随着润湿而降低,则液体会向管内上升渗入(\(\gamma_{\text{SL}}<\gamma_{\text{SO}}\)). 考虑液体上升的驱动力来自于附加压力,则由弯 ...