一、Kotlin的介绍
(一)Kotlin的优势
- 1、全面支持Lambda表达式 ⭐️
- 2、数据类(Data classes)⭐️
- 3、函数字面量和内联函数(Function literals & inline functions)⭐️
- 4、函数扩展(Extension functions)⭐️
- 5、空安全(Null safety)⭐️
- 6、智能转换(Smart casts)⭐️
- 7、字符串模版(String templates)
- 8、主构造函数(Primary constructors)
- 9、类委托(Class delegation)⭐️
- 10、类型推断(Type inference)
- 11、单例(Singletons)
- 12、声明点变量(Declaration-site variance)
- 13、区间表达式(Range expressions)
(二)Kotlin相关官网
1、下载网站
1)Kotlin的官网 https://kotlinlang.org/
以下是开发Kotlin的工具,推荐使用IDEA
2)Jetbrains Idea官网 https://www.jetbrains.com/idea/download/
3)命令行工具 http://kotlinlang.org/docs/tutorials/command-line.html
2、Kotlin学习网站
二、Kotlin的基础
(一)Hello word
所有的新语言都从Hello word 开始,请先记住这种写法
(二)变量的声明和使用:var
程序中的数据都必须通过变量来处里,处里不同的数据,必须使用不同的变量类型
fun main(args: Array<String>) {
// 1、计算机分配了一个空间name,里面存放的是字符串类型的数据,值为“张三”
var name = "张三"
// 2、将name空间重新赋值,值为“李四”
name = "李四"
// 3、name已经是String类型,无法转换为Int类型,所以这样写会报错
name = 8
}
1、在kotlin中通过关键字
var
来定义变量
2、var name = “李四”,然后name = 8
编译报错
,因为name变量已经定义为
String
类型,就无法自动转换为
Int
类型
(三)常见容器类型
不同的数据类型用不同的容器类型保存
Kotlin和Java不同,所有的数据类型都是类对象,而不是关键字
数据类型 | 取值范围 | 存储单位 |
---|---|---|
Byte | 整数-128~127 | 8块存储单位 8bit |
Short | 整数-32768~32767 | 16块存储单位 16bit |
Int | 整数-2147483648~2147483647 | 32块存储单位 32bit |
Long | 整数-9223372036854775808~9223372036854775807 | 64块存储单位 64bit |
Float | 小数,小数点可以精确到6位 | 符号位:1bit,指数位:11bit,尾数位:23bit |
Double | 小数,小数点可以精确到15~16位 | 符号位:1bit,指数位:11bit,尾数位:52bit |
String | 字符串,用""双引号引起来的字符串都可以存储 |
fun main(args: Array<String>) {
var maxByte: Byte = Byte.MAX_VALUE
var minByte: Byte = Byte.MIN_VALUE
println("Byte的最大值:" + maxByte)
println("Byte的最小值:" + minByte)
var maxInt: Int = Int.MAX_VALUE
var minInt: Int = Int.MIN_VALUE
println("Int的最大值:" + maxInt)
println("Int的最小值:" + minInt)
var maxLong: Long = Long.MAX_VALUE
var minLong: Long = Long.MIN_VALUE
println("Long的最大值:" + maxLong)
println("Long的最小值:" + minLong)
// var maxString: String = String.MAX_VALUE String没有取值范围
}
结果打印:
(四)类型推断(Type inference)
Kotlin会通过类型判断自动推断数据类型
案例【1】
自动类型推断为
Int
, 再次赋值
Long
范围的值,
编译报错
fun main(args: Array<String>) {
var i = 18 // 计算机开辟一块整数的存储空间,名字为i
i = 19
i = 9999999999 // i的类型推断为Int, 范围在-2147483648 ~ 2147483647
}
案例【2】
s的类型推断为
String
,不可以赋值整数123
fun main(args: Array<String>) {
var s = "haha" // 计算机开辟一块字符串的存储空间,名字为s
s = 123 // s的类型推断为String,不可以赋值整数123
}
(五)显示类型声明
可以通过显示的方式来指定数据类型
1、显示定义为Int
2、显示定义为Long
3、显示定义为String
4、显示定义为Short
变量d已经定义为
Short
类型,
Short
类型的取值范围在-128~127,再次赋值255已经超出了
Byte
类型的范围,
编译报错
var d:Byte = 18
d = 255 // 255超出了Byte类型的范围
5、【注意】定义变量时,如果不赋值,必须制定显示类型声明,否则自动类型判断,kotlin无法知道类型
var e // 自动类型判断必须是 = 后面确定了具体的类型,否则会报错,Kotlin不知道类型
var e:String // 指定了显示类型声明,Kotlin知道类型,就不会报错
(六)常量:val
- 变量是一个容器,里面存放的是可读可写的数据
- 常量是一个容器,里面存放的是只读的数据
fun main(args: Array<String>) {
/**
* 变量
*/
var number1 = "NO.123"
number1 = "NO.234"
/**
* 常量
*/
val number2 = "NO.123"
number2 = "NO.234" // number2 是常量,再次赋值,就会报错
}
常量再次赋值
编译报错
(七)Boolean布尔类型
Boolean布尔类型:
- true 真
- false 假
【例1】比较两个数的大小
fun main(args: Array<String>) {
var num1 = 4
var num2 = 6
println(num1 > num2) // 打印结果:false
}
【例2】比较 5 − 4 \sqrt5-\sqrt4 5
−4
和 4 − 3 \sqrt4-\sqrt3 4
−3
大小
fun main(args: Array<String>) {
var num3 = Math.sqrt(5.0) - Math.sqrt(4.0) // 使用Java lang 包下的数学类Math
var num4 = Math.sqrt(4.0) - Math.sqrt(3.0)
println(num3 > num4) // 打印结果:false
}
【例3】比较 2100 和 375 的大小
fun main(args: Array<String>) {
var num5 = Math.pow(2.0, 100.0) // 使用Java lang 包下的数学类Math
var num6 = Math.pow(3.0, 75.0)
println(num5 < num6) // 打印结果:true
}
(八)函数
函数是计算机执行命令的单元
计算机里面的函数就是程序执行的小片段,这些小片段可以有机的组合在一起,完成一个复杂的业务能力
我们编写的函数一般都是用来处理数据,解析数据,将参数交给函数,函数处理完毕,产生输出
1、Kotlin函数编写规则
2、Main函数
main
函数说Kotlin程序的入口海曙,是计算器运行起来第一个运行的函数
3、println() 函数
println
函数就是讲括号里面的内容打印到控制台
【例子】打印一个菱形
/**
* 打印菱形
* *
* ***
* *****
* ***
* *
*/
fun main() {
print1star()
print3star()
print5star()
print3star()
print1star()
}
/**
* 自定义函数
*/
fun print1star() {
println(" * ")
}
fun print3star() {
println(" *** ")
}
fun print5star() {
println("*****")
}
打印结果:
3、自定义函数
【例1】编写一个小型计算器
fun main(args: Array<String>) {
var a = 8
var b = 2
println(add(a, b))
println(sub(a, b))
println(mutl(a, b))
println(devide(a, b))
}
/**
* 加法
* fun:固定写法
* add:函数名字
* a: 第一个参数,类型Int
* b: 第二个参数,类型Int
* : Int 表示返回值为Int类型
*/
fun add(a: Int, b: Int): Int {
return a + b
}
fun sub(a: Int, b: Int): Int {
return a - b
}
fun mutl(a: Int, b: Int): Int {
return a * b
}
fun devide(a: Int, b: Int): Int {
return a / b
}
【例2】编写函数练习
/**
* 请编写函数,函数名为sayHello,方法返回值是String类型,一个参数是String类型,名称为name
*/
fun sayHello(name: String): String {
return "我叫" + name
}
/**
* 轻便鞋函数,函数名为checkAge,方法的返回值是Boolean类型,一个参数是整数类型,名称为age
*/
fun checkAge(age: Int): Boolean {
return if(age == 18) true else false
}
/**
* 请编写函数,函数名为saveLog,方法没有返回值,一个参数是整数类型,名称为logLevel
* 没有返回值是:Unit,Unit可以省略不写
*/
fun saveLog(logLevel: Int):Unit {
println("保存成功" + logLevel)
}
(九)字符串模版
问:who are you ? How old are you ?
- Java:“I’m” + name + “. I’m " + age + " years old.”
- Kotlin:“I’m${name}. I’m ${age} years old.”
1、Kotlin中采用了
${}
来实现字符串填充,去掉了Java中繁琐的字符串拼接。
2、当字符串中需要填充的只有一个变量时,并且右边有标点符号或者空格,可以省略
{}
,比如
$placeName
3、
${}
可以写任意的表达式,比如
${placeName.length}
4、如果需要在原生字符串中表示字面值 $ 字符(它不支持反斜杠转义),比如
${'$'}
【例子】日记生成器
fun main(args: Array<String>) {
println(diaryGenerater("金銮殿", 100.0f))
}
fun diaryGenerater(placeName: String, price: Float): String {
return "今天爸爸、妈妈带着我去参观了$placeName, 这${placeName.length}个字的地方,花了${'$'}${price}钱"
}
(十)条件控制 if-else
问:求两个数的最大值
- Java:return a > b ? a : b
- Kotlin:return if (a > b) a else b
1、Kotlin中没有三元表达式,因为
if-else
有返回值,可以直接替代三元表达式
2、
if-else
的返回值在条件控制中的最后一行
3、
if-else
的返回值不是必须的,可以有,也可以没有
4、
if-else
因为有返回值,可以直接复制给变量
【方法一】求两个数的最大值:普通的
if-else
写法
fun max(num1: Int, num2: Int): Int {
if (num1 > num2) return num1 else return num2
}
【方法二】求两个数的最大值:直接返回
if-else
的返回值的写法
fun max(num1: Int, num2: Int): Int {
return if (num1 > num2) num1 else num2
}
【方法三】求两个数的最大值:将
if-else
赋值给变量的写法
fun max(num1: Int, num2: Int): Int {
var max = if (num1 > num2) num1 else num2
return max
}
(十一)when表达式
- Java:switch
- Kotlin:when (更加强大的switch) ,将它的参数和所有的分支条件顺序比较,直到某个分支满足条件
1、when条件:具体数据 – 常量
when (num) {
1 -> println("当前数据 = 1")
2, 3, 4-> println("当前数据 = 2,3,4")
else -> println("其他数据 = $num")
}
2、when条件:具体数据 – 任意表达式
when (num) {
parseInt(x) -> println("当前数据 = 1")
else -> println("其他数据 = $num")
}
3、when条件:区间范围:in、!in
-
检测when的条件,在一个区间范围内in
-
检测when的条件,不在一个区间范围内!in
var validNumbers = 11..20
when (num) {
in 1..10 -> println("当前数据在1~10的范围内")
in validNumbers -> println("当前数据在11~20的范围内")
!in 21..30 -> println("当前数据在21~30的范围内")
else -> println("其他数据 = $num")
}
3、when条件:特定类型的值:is、!is
-
检测when的条件,是一个特定类型的值is
-
检测when的条件,不是一个特定类型的值!in
when (num) {
is String -> println("当前数据是String类型")
is Int -> println("当前数据是Int类型")
!is Boolean -> println("当前数据不是Boolean类型")
else -> println("其他数据类型")
}
4、when条件:枚举类
enum class Week {
星期一, 星期二, 星期三, 星期四, 星期五, 星期六, 星期天
}
fun judgeNum(num: Week) {
var result = when (num) {
Week.星期一,Week.星期二,Week.星期三 -> println("当前属于星期一到星期三")
else -> println("其他星期")
}
}
5、when不提供参数可以取代if-else-if
1、
when
可以用来取代
if-else-if
链
2、不提供参数时,所有的分支条件都是布尔表达式
when {
a > b -> println("a > b")
a < b -> println("a < b")
else -> println("a = b")
}
6、when有返回值
1、
when
有返回值,可以赋值给变量
2、
when
有返回值,可以直接返回值
var result = when (num) {
is String -> true
else -> false
}
(十二)字符串比较
问:比较两个字符串str1 = “danke”,str2 = "danke"是否相等
- Java:str1 == str2 // false, 因为Java比较的是两个字符串的地址是否相等
- Kotlin:str1 == str2 // true, 因为Kotlin比较的是两个字符串的值是否相等
1、 ==
比较值相等,相当于 equals
==
equals
fun main(args: Array<String>) {
var str1 = String("danke".toByteArray())
var str2 = String("danke".toByteArray())
println(str1 == str2) // 打印结果:true
println(str1.equals(str2)) // 打印结果:true
}
2、比较大小是否忽略大小写
equals(String, boolean)
第二个参数true:忽略,false:不忽略
fun main(args: Array<String>) {
var str3 = "danke"
var str4 = "Danke"
println(str3.equals(str4, true)) // 打印结果:true
println(str3.equals(str4, false)) // 打印结果:false
}
3、 ===
比较对象的地址相等
===
(1)需要将常量字符串装换为String对象,才能验证
===
比较的是引用
fun main(args: Array<String>) {
var str1 = String("danke".toByteArray())
var str2 = String("danke".toByteArray())
println(str1 === str2) // 打印结果:false
}
(2)和Java一样,Kotlin也有常量池,常量池中的数据,比较都是相等的(具体可以翻阅我的Java基础篇
==
和
equals
的区别)
fun main(args: Array<String>) {
var str1 = "danke"
var str2 = "danke"
println(str1 === str2) // 打印结果:true
}