01Kotlin基础知识
2021-09-10 13:05:36 0 举报
AI智能生成
Kotlin语言学习笔记与基础知识点讲解
作者其他创作
大纲/内容
Kotlin学习笔记1-5
1.如何对Kotlin进行空检测机制
var name:String ? =null
?:加上?,就相当于一种广播,告诉所有的使用,在使用的时候,要注意,可能为空的情况,在使用的时候,要解决这个问题,不然是不能随便使用的。
var name:String ? = "Hello Kotlin"
name?.length
var name:String ? = "Hello Kotlin"
name?.length
第一种补救方法:
TODO 第一种补救措施,name如果真的为null,后面的不执行,就不会引发空指针异常。如:name?.length
第二种补救方法:
TODO 无论name是不是null,都执行,与java没有什么区别,当为null的时候,会报空指针异常。如:name!!.length
第三种补救方法:
TODO 与java中一样,进行null判断,之后在使用。如:if(name !=null) name.length
说明:当某个变量的值可以为 null 的时候,必须在声明处的类型后添加 ? 来标识该引用可为空
2.Kotlin语言的val与var类型推断
不用指定属性的具体类型,可以根据值进行自动推断
val name = "qwety"
思考:Kotlin是静态语言,还是,动态语言?
解析:因为在编译期就决定了,属性的类型,是String类型,所以
答案:是静态语言。
思考:Kotlin是静态语言,还是,动态语言?
解析:因为在编译期就决定了,属性的类型,是String类型,所以
答案:是静态语言。
3.Kotlin中的函数、方法与java的对比
kotlin中的方法与java的方法不同
kotlin方法
fun add(){
}
上面就是一个完整的方法,他的返回值为Unit
其中隐士的Unit == java void
}
上面就是一个完整的方法,他的返回值为Unit
其中隐士的Unit == java void
fun(number1:Int ,number2:Int) :Int{
return number1+number1
}
此方法是明确了返回为Int类型的数据。与java方法一样。
简写的方法:
fun(number1:Int,number2:Int):Int = number1+number2
return number1+number1
}
此方法是明确了返回为Int类型的数据。与java方法一样。
简写的方法:
fun(number1:Int,number2:Int):Int = number1+number2
类型推导
fun add2(number1:int,number2:Int) = number1+number2
fun add3(number1:int,number2:Int) = number1+number2.toDouble()
fun method02() = "kotlin"
fun method03() = 'Chart'
fun add2(number1:int,number2:Int) = number1+number2
fun add3(number1:int,number2:Int) = number1+number2.toDouble()
fun method02() = "kotlin"
fun method03() = 'Chart'
4.学习Kotlin语言的重要性
各个语言精华集聚一身的新时代语言
Kotlin走的是全栈语言之路
5.Kotlin语言声明变量与内置类型
声明
可读可写变量声明
var name :String = "hxf"
var 可读可写
name变量名
String类型
“hxf”值
var 可读可写
name变量名
String类型
“hxf”值
只读变量声明
val name :String = "hxf"
var 只读(与javafinal相似)
name变量名
String类型
“hxf”值
var 只读(与javafinal相似)
name变量名
String类型
“hxf”值
内置类型
String 字符串
Char 单字符
Boolean true/false
Int 整型
Double 小数
List 集合
Set 无重复的元素集合
Map 键值对集合
Char 单字符
Boolean true/false
Int 整型
Double 小数
List 集合
Set 无重复的元素集合
Map 键值对集合
类型推断
val info:String = “hxf”
此时的String类型可以省略,因为kotlin语言会根据“hxf”这个字符串类自动推断info为String类型。
此时的String类型可以省略,因为kotlin语言会根据“hxf”这个字符串类自动推断info为String类型。
Kotlin学习笔记6-10
6.Kotlin在编译时常量,const其实与java中的final static相似
编译时常量智能是长阳的基本数据类型
Sting
Double
Int
Float
Long
Short
Byte
Char
Boolean
Double
Int
Float
Long
Short
Byte
Char
Boolean
示例代码:
const val PI = 3.1415
fun main(){
val info = "hxf"//这个成为只读类型的变量
//提示:修饰符const不适用于 局部变量(const修饰符修饰的为编译时变量)
//const val PI = 45
}
const val PI = 3.1415
fun main(){
val info = "hxf"//这个成为只读类型的变量
//提示:修饰符const不适用于 局部变量(const修饰符修饰的为编译时变量)
//const val PI = 45
}
说明
编译时常量智能在函数之外定义,为什么呢?
答:如果在函数内定义,就必须在运行时才能调用函数赋值,何来编译时常量一说。
结论:编译时常量只能在函数之外定义,就可以在编译期间初始化了。
答:如果在函数内定义,就必须在运行时才能调用函数赋值,何来编译时常量一说。
结论:编译时常量只能在函数之外定义,就可以在编译期间初始化了。
kotlin语言:
const val PI = 3.1415
Java语言:
public final static Double PI = 3.1415
const val PI = 3.1415
Java语言:
public final static Double PI = 3.1415
7.如何查看Kotlin语言反编译后的字节码
位置:Tool->Kotlin->show kotlin bytecode
点击 decompile 查看java代码
kotlin语言:
const val PI = 3.1415
Java语言:
public final static Double PI = 3.1415
const val PI = 3.1415
Java语言:
public final static Double PI = 3.1415
因为要运行到JVM上,所以会给生成一个类来包含const编译时变量
8.Kotlin语言的引用类型
Java有两种数据类型
1、基本类型:int、double
2、引用类型:String等
1、基本类型:int、double
2、引用类型:String等
Kotlin语言
kotlin中看起来都是引用类型,实际上编译器会在java字节码中,修改成“基本类型”
kotlin中看起来都是引用类型,实际上编译器会在java字节码中,修改成“基本类型”
9.Kotlin语言的range表达式
range 是范围 从哪里 到哪里?
var number:Int = 99
if(number in 1.. 100){
}
if(number in 1.. 100){
}
10.Kotlin中的when表达式
val week = 5
val info when(week){
1->"今天是周二,非常的忙"
2->"今天是周三,也是很忙"
else ->{
}
}
如果不确定的时候,返回的类型就是any
val info when(week){
1->"今天是周二,非常的忙"
2->"今天是周三,也是很忙"
else ->{
}
}
如果不确定的时候,返回的类型就是any
1.Java的if是语句
2.KT 的 if是表达式,是有返回值的
2.KT 的 if是表达式,是有返回值的
Kotlin学习笔记11-15
11.Kotlin语言的String模板
模板其实很简单,只不过在使用的时候,${name}这样使用
还有就是在内容里面添加if判断等
如:
${if (isLogin) "成功" else "失败"}
如:
${if (isLogin) "成功" else "失败"}
12.Kotlin语言的函数头/函数的默认值
函数默认都是public
但是相对于java而言,Kotlin的函数,更加的规范,现有输入,再有输出
伪代码如下:(输入):输出{
}
例如函数:
private fun method01(age:Int,name:String):Int{
println("你的姓名是$name,你的年龄是$age")
return 200
}
但是相对于java而言,Kotlin的函数,更加的规范,现有输入,再有输出
伪代码如下:(输入):输出{
}
例如函数:
private fun method01(age:Int,name:String):Int{
println("你的姓名是$name,你的年龄是$age")
return 200
}
函数参数设置默认值
例如函数:
private fun method01(age:Int = 56 ,name:String):Int{
println("你的姓名是$name,你的年龄是$age")
return 200
}
参数默认值:
age:Int = 56,这个是我们给的默认值,在进行方法调用的时候,就可以不用管这个值,
但是如果要是传值的话,传入的值就会把56给替换掉。
例如函数:
private fun method01(age:Int = 56 ,name:String):Int{
println("你的姓名是$name,你的年龄是$age")
return 200
}
参数默认值:
age:Int = 56,这个是我们给的默认值,在进行方法调用的时候,就可以不用管这个值,
但是如果要是传值的话,传入的值就会把56给替换掉。
13.Kotlin语言的Unit函数特点
Unit不写,默认也是有的,Unit代表五参数返回的 忽略类型 == Unit类型类
Java语言的void关键字(void是 无参数返回的,忽略类型)
Java语言的void关键字(void是 无参数返回的,忽略类型)
private fun dowork01():Unit{
}
上面是默认的有Unit的
}
上面是默认的有Unit的
14.Kotlin语言的Nothing类型特点
示例代码:
private fun show (number:Int){
when(number){
-1->TODO("没有这个事情")
in 0..59 ->println("分数不及格")
in 60..70->println("分数及格")
in 71..100->println("分数优秀")
}
}
private fun show (number:Int){
when(number){
-1->TODO("没有这个事情")
in 0..59 ->println("分数不及格")
in 60..70->println("分数及格")
in 71..100->println("分数优秀")
}
}
说明
当所有的条件不满足的时候,就会执行TODO的Nothing函数,报错,并打印自己定义的内容。
Kotlin基础知识
基础
基本类型
基本类型说明:
在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数与属性。 一些类型可以有特殊的内部表示——例如,数字、字符以及布尔值可以在运行时表示为原生类型值,但是对于用户来说,它们看起来就像普通的类
在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数与属性。 一些类型可以有特殊的内部表示——例如,数字、字符以及布尔值可以在运行时表示为原生类型值,但是对于用户来说,它们看起来就像普通的类
数字
数字说明:
Kotlin 提供了一组表示数字的内置类型。 对于整数,有四种不同大小的类型,因此值的范围也不同
Kotlin 提供了一组表示数字的内置类型。 对于整数,有四种不同大小的类型,因此值的范围也不同
1.
类型:Byte
大小(比特数):8
最小值:-128
最大值:127
类型:Byte
大小(比特数):8
最小值:-128
最大值:127
2.
类型:Short
大小(比特数):16
最小值:-32768
最大值:32767
类型:Short
大小(比特数):16
最小值:-32768
最大值:32767
3.
类型:Int
大小(比特数):32
最小值:
最大值:
类型:Int
大小(比特数):32
最小值:
最大值:
4.
类型:Long
大小(比特数):64
最小值:
最大值:
类型:Long
大小(比特数):64
最小值:
最大值:
5.
类型:Float
大小(比特数):32
最小值:
最大值:
类型:Float
大小(比特数):32
最小值:
最大值:
6.
类型:Double
大小(比特数):64
最小值:
最大值:
类型:Double
大小(比特数):64
最小值:
最大值:
示例:(1-4)
例如:
val one = 1 // Int
val threeBillion = 3000000000 // Long
val oneLong = 1L // Long
val oneByte: Byte = 1
val one = 1 // Int
val threeBillion = 3000000000 // Long
val oneLong = 1L // Long
val oneByte: Byte = 1
所有以未超出 Int 最大值的整型值初始化的变量都会推断为 Int 类型。如果初始值超过了其最大值,那么推断为 Long 类型。 如需显式指定 Long 型值,请在该值后追加 L 后缀
示例:(5-6)
例如:
val pi = 3.14 // Double
val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float,实际值为 2.7182817
val pi = 3.14 // Double
val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float,实际值为 2.7182817
对于以小数初始化的变量,编译器会推断为 Double 类型。 如需将一个值显式指定为 Float 类型,请添加 f 或 F 后缀。 如果这样的值包含多于 6~7 位十进制数,那么会将其舍入
(1)数字字面值中的下划线,使用下划线使数字常量更易读
例如:
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
(2)表示方式
在 Java 平台数字是物理存储为 JVM 的原生类型,除非我们需要一个可空的引用(如 Int?)或泛型。 后者情况下会把数字装箱
注意数字装箱不一定保留同一性
注意数字装箱不一定保留同一性
例如:
val a: Int = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a
val b: Int = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b
println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // false
val a: Int = 100
val boxedA: Int? = a
val anotherBoxedA: Int? = a
val b: Int = 10000
val boxedB: Int? = b
val anotherBoxedB: Int? = b
println(boxedA === anotherBoxedA) // true
println(boxedB === anotherBoxedB) // false
保留了相等性
例如:
val a: Int = 10000
println(a == a) // 输出“true”
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA == anotherBoxedA) // 输出“true”
val a: Int = 10000
println(a == a) // 输出“true”
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA == anotherBoxedA) // 输出“true”
(3)显示转换
由于不同的表示方式,较小类型并不是较大类型的子类型。 如果它们是的话,就会出现下述问题
例如:
// 假想的代码,实际上并不能编译:
val a: Int? = 1 // 一个装箱的 Int (java.lang.Integer)
val b: Long? = a // 隐式转换产生一个装箱的 Long (java.lang.Long)
print(b == a) // 惊!这将输出“false”鉴于 Long 的 equals() 会检测另一个是否也为 Long
// 假想的代码,实际上并不能编译:
val a: Int? = 1 // 一个装箱的 Int (java.lang.Integer)
val b: Long? = a // 隐式转换产生一个装箱的 Long (java.lang.Long)
print(b == a) // 惊!这将输出“false”鉴于 Long 的 equals() 会检测另一个是否也为 Long
较小的类型不能隐式转换为较大的类型
每个数据类型都有以下转换
例如:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
(4)整数除法
整数间的除法总是返回整数,但会丢弃小数部分
例如:
val x = 5 / 2
//println(x == 2.5) // ERROR: Operator '==' cannot be applied to 'Int' and 'Double'
println(x == 2)
结果true
val x = 5 / 2
//println(x == 2.5) // ERROR: Operator '==' cannot be applied to 'Int' and 'Double'
println(x == 2)
结果true
对于任何两个整数类型之间的除法来说都是如此
例如:
val x = 5L / 2
println(x == 2L)
val x = 5L / 2
println(x == 2L)
(5)位运算
完整的位运算列表(只用于 Int 与 Long)
例如:
shl(bits)- 有符号左移
shr(bits) -有符号右移
ushr(bits) – 无符号右移
and(bits) – 位与
or(bits) – 位或
xor(bits) – 位异或
inv() – 位非
shl(bits)- 有符号左移
shr(bits) -有符号右移
ushr(bits) – 无符号右移
and(bits) – 位与
or(bits) – 位或
xor(bits) – 位异或
inv() – 位非
(6)浮点比较
例如:
相等性检测:a == b 与 a != b
比较操作符:a < b、 a > b、 a <= b、 a >= b
区间实例以及区间检测:a..b、 x in a..b、 x !in a..b
相等性检测:a == b 与 a != b
比较操作符:a < b、 a > b、 a <= b、 a >= b
区间实例以及区间检测:a..b、 x in a..b、 x !in a..b
字符
(1)字符用 Char 类型表示,它们不能直接当作数字。
例如:
fun check(c: Char) {
if (c == 1) { // 错误:类型不兼容
// ……
}
}
fun check(c: Char) {
if (c == 1) { // 错误:类型不兼容
// ……
}
}
(2)字符字面值用单引号括起来: '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() // 显式转换为数字
}
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 显式转换为数字
}
布尔
(1)布尔用 Boolean 类型表示,它有两个值:true 与 false
(2)内置的布尔运算
例如:
|| 短路逻辑或
&& 短路逻辑与
! 逻辑非
|| 短路逻辑或
&& 短路逻辑与
! 逻辑非
数组
(1)数组在 Kotlin 中使用 Array 类来表示,它定义了 get 与 set 函数(按照运算符重载约定这会转变为 [])以及 size 属性,以及一些其他有用的成员函数
例如:
class Array<T> private constructor() {
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ……
}
class Array<T> private constructor() {
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ……
}
(2)可以使用库函数 arrayOf() 来创建一个数组并传递元素值给它,这样 arrayOf(1, 2, 3) 创建了 array [1, 2, 3]。 或者,库函数 arrayOfNulls() 可以用于创建一个指定大小的、所有元素都为空的数组
例如:
// 创建一个 Array<String> 初始化为 ["0", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }
// 创建一个 Array<String> 初始化为 ["0", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }
(3)原生数组
例如:
原生类型数组: ByteArray、 ShortArray、IntArray
// 大小为 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 }
原生类型数组: ByteArray、 ShortArray、IntArray
// 大小为 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 }
无符号整型
例如:
kotlin.UByte: 无符号 8 比特整数,范围是 0 到 255
kotlin.UShort: 无符号 16 比特整数,范围是 0 到 65535
kotlin.UInt: 无符号 32 比特整数,范围是 0 到 2^32 - 1
kotlin.ULong: 无符号 64 比特整数,范围是 0 到 2^64 - 1
kotlin.UByte: 无符号 8 比特整数,范围是 0 到 255
kotlin.UShort: 无符号 16 比特整数,范围是 0 到 65535
kotlin.UInt: 无符号 32 比特整数,范围是 0 到 2^32 - 1
kotlin.ULong: 无符号 64 比特整数,范围是 0 到 2^64 - 1
字符串
(1)字符串用 String 类型表示,字符串是不可变的
(2)可以通过 trimMargin() 函数去除前导空格
例如:
val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
""".trimMargin()
val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
""".trimMargin()
控制流
if 表达式
(1)Kotlin 中,if是一个表达式,即它会返回一个值。 因此就不需要三元运算符(条件 ? 然后 : 否则),因为普通的 if 就能胜任这个角色
例如:
// 传统用法
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// 作为表达式
val max = if (a > b) a else b
// 传统用法
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// 作为表达式
val max = if (a > b) a else b
(2)if的分支也可以是代码块,最后的表达式作为该块的值
例如:
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
When 表达式
(1)when 表达式取代了类 C 语言的 switch 语句
例如:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x is neither 1 nor 2")
}
}
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x is neither 1 nor 2")
}
}
when 将它的参数与所有的分支条件顺序比较,直到某个分支满足条件。 when 既可以被当做表达式使用也可以被当做语句使用,
如果它被当做表达式, 符合条件的分支的值就是整个表达式的值,如果当做语句使用, 则忽略个别分支的值
如果它被当做表达式, 符合条件的分支的值就是整个表达式的值,如果当做语句使用, 则忽略个别分支的值
(2)如果 when 作为一个表达式使用,则必须有 else 分支, 除非编译器能够检测出所有的可能情况都已经覆盖了
例如:
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
For 循环
(1)for 循环可以对任何提供迭代器(iterator)的对象进行遍历,这相当于像 C# 这样的语言中的 foreach 循环
例如:
for (item in collection) print(item)
代码块:
for (item: Int in ints) {
// ……
}
区间表达式:
for (i in 1..3) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
for (item in collection) print(item)
代码块:
for (item: Int in ints) {
// ……
}
区间表达式:
for (i in 1..3) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
While 循环
(1)while 与 do..while 照常使用
例如:
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在此处可见
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y 在此处可见
返回和跳转
Kotlin 有三种结构化跳转表达式
return默认从最直接包围它的函数或者匿名函数返回
break终止最直接包围它的循环
continue继续下一次最直接包围它的循环
类与对象
类与继承
属性与字段
接口
函数式(SAM)接口
可见性修饰符
扩展
数据类
密封类
泛型
嵌套类
枚举类
对象
类型别名
内联类
委托
委托属性
函数与lambda表达式
函数
lambda表达式
内联函数
集合
迭代器
区间与数列
序列
操作概述
转换
过滤
加减操作符
分组
单个元素提取
排序
聚合操作
集合写操作
List相关操作
Set相关操作
Map相关操作
协程
取消与超时
组合挂起函数
协程上下文与调度器
异步流
通道
异常处理与监督
共享可变状态与并发
Select表达式
0 条评论
下一页