Kotlin学习(一):Kotlin基础知识

定义变量常量

在Kotlin中,定义变量时有以下几点与java不同:

  • 位置不同:在 Kotlin 中,数据类型要放到变量后面,并且用冒号(:)分隔,这正好和 Java 相反。
  • 变量和常量需要关键字:在 Kotlin 中,定义变量需要用 var 开头,定义常量需要用 val 。
  • 数据类型首字母:在 Kotlin 中,数据类型都以大写字母开头,而在 Java 中,一般只有类、接口等复杂数据类型的名字才采用首字母大写的方式。
  • 如果在定义变量时未进行初始化,就必须指定数据类型,如果在定义变量或者常量时进行了初始化,就可以不指定数据类型,Kotlin编译器会自动根据等号右侧的值推导数据类型。
 private var m: Int = 30 // 定义变量private val n: Int = 20 // 定义常量,值不可改变private var k = 40 // 自动推导出变量的数据类型private val a = 10 // 自动推导出常量的数据类型

**延迟初始化属性与变量:**一般地,属性声明为非空类型必须在构造函数中初始化。 然而,这经常不方便。例如:属性可以通过依赖注入来初始化, 或者在单元测试的 setup 方法中初始化。 这种情况下,你不能在构造函数内提供一个非空初始器。 但你仍然想在类体中引用该属性时避免空检测。为处理这种情况,你可以用 lateinit 修饰符标记该属性:

lateinit var name: String // 非空属性延迟初始化

定义函数

在kotlin中,函数定义使用fun关键字,参数格式为 参数:类型 ,最后函数返回值类型,如下:

fun add(a:Int,b:Int):Int{return a+b
}

如果函数没有返回值,可以返回Unit,也可以什么都不返回(省略Unit):

fun printSum(a:Int,b:Int){println("sum = ${a+b}")
}

基础数据类型

在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数与属性。 一些类型可以有特殊的内部表示——例如,数字、字符以及布尔值可以在运行时表示为原生类型值,但是对于用户来说,它们看起来就像普通的类。 在本节中,我们会描述 Kotlin 中使用的基本类型:数字、字符、布尔值、数组与字符串。

数值类型

Kotlin 提供了一组表示数字的内置类型。 对于整数,有四种不同大小的类型,因此值的范围也不同。

类型 字节大小(Bytes) 位大小(Bits) 最小值 最大值
Byte 1 8 -128 127
Short 2 16 -32768 32727
Int 4 32 - 2^31 2^31-1
Long 8 64 -2^63 2^63-1

对于浮点数,Kotlin 提供了 FloatDouble 类型。Float为单精度,而Double为双精度。

类型 大小(比特数) 有效数字比特数 指数比特数 十进制位数
Float 32 24 8 6-7
Double 64 53 11 15-16

对于以小数初始化的变量,编译器会推断为 Double 类型。 如需将一个值显式指定为 Float 类型,请添加 fF 后缀。 如果这样的值包含多于 6~7 位十进制数,那么会将其舍入。

字面常量: 数值常量字面值有以下几种:

  • 十进制: 123

    • Long 类型用大写 L 标记: 123L
  • 十六进制: 0x0F
  • 二进制: 0b00001011

注意: 不支持八进制

Kotlin 同样支持浮点数的常规表示方法:

  • 默认 double:123.5123.5e10
  • Float 用 f 或者 F 标记: 123.5f

数字字面值中的下划线: 你可以使用下划线使数字常量更易读:

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

类型转换: java中可以通过隐式类型转换,数值大的类型可以转换成数据小的类型,但是这样往往会丢失精度,在kotlin中由于不同的表示方式,较小类型并不是较大类型的子类型,较小的类型不能隐式转换为较大的类型。 这意味着在不进行显式转换的情况下我们不能把 Byte 型值赋给一个 Int 变量,每种数据类型都有下面的这些方法,可以转化为其它的类型:

toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char

位运算: 对于位运算,没有特殊字符来表示,而只可用中缀方式调用具名函数,例如:

val x = (1 shl 2) and 0x000FF000

这是完整的位运算列表(只用于 IntLong):

  • shl(bits) – 有符号左移
  • shr(bits) – 有符号右移
  • ushr(bits) – 无符号右移
  • and(bits) – 位
  • or(bits) – 位
  • xor(bits) – 位异或
  • inv() – 位非

字符类型

在Kotlin语言中,字符类型用Char 表示,不过与java 不同的是,字符不能直接看成是数字(可以通过显示转换char.toInt()),Char 必需是单引号 ’ 包含起来的。比如普通字符 ‘0’,‘a’,字符字面值用单引号括起来: ‘1’。 特殊字符可以用反斜杠转义。 支持这几个转义序列:\t、 \b、\n、\r、\’、\"、\\ 和 \$。

 fun check(c:Char){if (c==1){ //编译失败}}fun check(c:Char){if (c=='1'){ //编译成功}}

布尔类型

布尔用 Boolean 类型表示,它有两个值:truefalse

若需要可空引用布尔会被装箱。

内置的布尔运算有:

  • || – 逻辑或
  • && – 逻辑与
  • ! - 逻辑非

数组

数组在 Kotlin 中使用 Array 类来表示,它定义了 getset 函数(按照运算符重载约定这会转变为 [])以及 size 属性,以及一些其他有用的成员函数:

class Array<T> private constructor() {val size: Intoperator fun get(index: Int): Toperator fun set(index: Int, value: T): Unitoperator fun iterator(): Iterator<T>// ……
}

我们可以使用库函数 arrayOf() 来创建一个数组并传递元素值给它,这样 arrayOf(1, 2, 3) 创建了 array [1, 2, 3]。 或者,库函数 arrayOfNulls() 可以用于创建一个指定大小的、所有元素都为空的数组。

另一个选项是用接受数组大小以及一个函数参数的 Array 构造函数,用作参数的函数能够返回给定索引的每个元素初始值:

// 创建一个 Array<String> 初始化为 ["0", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }
// 使用arrayOf可以定义存储任意值的数组
var arr1 = arrayOf(1, 2, 3, "hello")
println(arr1[3])// 使用 arrayOfNulls 定义固定长度的数组
var arr2 = arrayOfNulls<Int>(10)
println(String.format("arr2数组的长度为%d", arr2.size))
println("arr2数组的长度为:".plus(arr2.size))// 使用 Array 构造器定义数组并初始化每个数组元素的值
var arr3 = Array(10) { i -> (i * i).toString() }
for (i in arr3.indices) {println(String.format("数组arr3第%d个元素的值为:%s", (i + 1), arr3[i]))
}
println(arr3[9])// 使用 intArrayOf, shortArrayOf 等函数定义指定类型的数组,井初始化数组
var arr4 = intArrayOf(10, 2, 30, 40)
for (i in arr4.indices) {println(String.format("arr4[%d]==%d ,", i, arr4[i]))
}

Kotlin 中数组是不型变的(invariant)。这意味着 Kotlin 不让我们把 Array<String> 赋值给 Array<Any>,以防止可能的运行时失败

字符串

在Kotlin中,使用String表示字符串类型,有如下两类字符串:

  • 普通字符串 这种字符串类似于 Ja ,可以在字符串中加上转义符,如 \n,会让转义符后面的字符串换到下 行,这种字符串需要放在双引号中。
  • 保留原始格式的字符串(raw string ):这种字符串不能使用转义符,如果字符串中带有格式,如换行,直接写在字符串中即可。这种字符串需要放在3个引号对中
 // 普通字符串,和 java 一样var s1 = "HELLO \nWORLD \n"// 保留源格式字符串,不能使用转义符var s2 = """HELLOWORLDAREYOUOK""".trimMargin()println(s1.plus(s2))

字符串模板

字符串字面值可以包含模板表达式 ,即一些小段代码,会求值并把结果合并到字符串中。 模板表达式以美元符($)开头,由一个简单的名字构成:

val i = 10
println("i = $i") // 输出“i = 10”

Target platform: JVMRunning on kotlin v. 1.5.31

或者用花括号括起来的任意表达式:

val s = "abc"
println("$s.length is ${s.length}") // 输出“abc.length is 3”

Target platform: JVMRunning on kotlin v. 1.5.31

原始字符串与转义字符串内部都支持模板。 如果你需要在原始字符串中表示字面值 $ 字符(它不支持反斜杠转义),你可以用下列语法:

val price = """
${'$'}9.99
"""

控制流:if、when、for、while

if表达式

在Kotlin中,if语句本身就是表达式,有返回值,因此,Kotlin并不需要像Java那样提供三元运算符(condition?then:else)。因为普通的if就胜任这个角色。

   // 传统用法var a = 20var b = 30var min = 0if (a > b) {println("a,b两者更小的数值是1:b=$b")} else {println("a,b两者更小的数值是2:a=$a")}a = 40b = 30if (a > b) min = bprintln("a,b两者更小的数值是3:a=$a,b=$b,min=$min")a = 50b = 40// 表达式用法min = if (a > b) b else aprintln("a,b两者更小的数值是4:a=$a,b=$b,min=$min")a = 90b = 100min = if (a > b) {b //返回值} else {a // 返回值}println("a,b两者更小的数值是5:a=$a,b=$b,min=$min")

when语句

在Kotlin中,when替换了C语言放个的switch语句。标准的when语句用法如下:

var x = 1
when (x) {1 -> println("x==1")2 -> println("x==2")else -> {println("x is neither 1 or 2")println("end")}
}

使用when语句时,需注意以下几点:

  • when 语句会根据传入的值(这里是x)寻找第一个满足条件的分支,找到后执行分支的语句。
  • 如果分支中多于 条语旬,要用{...}
  • 满足条件的分支执行后,会自动终止 when 语句的执行,因此,并不需要像 switch句那样每 case 语句都加上 break

when与if一样,既可以作为语句使用,也可以作为表达式使用。如果是后者,when语句的第一个满足条件的分支的最后一个表达式就是when表达式的返回值。

 // when 作为表达式时使用var x = 1var m = when (x) {1 -> 202 -> 30else -> 50}println("m的值是:$m") // 打印结果:m的值是:20

如果其他分支都不满足条件将会求值 else 分支。 如果 when 作为一个表达式使用,则必须有 else 分支, 除非编译器能够检测出所有的可能情况都已经覆盖了[例如,对于 枚举(enum)类条目与密封(sealed)类子类型]。如果很多分支需要用相同的方式处理,则可以把多个分支条件放在一起,用逗号分隔:

// 如果符合多个条件,条件之间可用","隔开
when (x) {1, 2, 3 -> println("符合条件")else -> println("不符合条件")
}

如果要执行相同代码的条件比较多,或无法枚举,可以使用 in 关键字确定一个范围,代码如下:

//使用 in 关键字
var n = 25
when (n) {in 1..10 -> println("不符合条件")in 11..20 -> println("符合条件")// !in 表示不在这个范围内!in 30..60 -> println("hello world")else -> println("条件未知")
}

还可以是检测一个值是(is)或者不是(!is)一个特定类型的值。注意: 由于智能转换,你可以访问该类型的方法与属性而无需任何额外的检测。

fun hasPrefix(x: Any) = when(x) {is String -> x.startsWith("prefix")else -> false
}

when 也可以用来取代 if-else if链。 如果不提供参数,所有的分支条件都是简单的布尔表达式,而当一个分支的条件为真时则执行该分支:

when {x.isOdd() -> print("x is odd")y.isEven() -> print("y is even")else -> print("x+y is odd.")
}

when中的分支条件不仅可以是常量,还可以是任意表达式:例如,下面的代码分支条件就是一个函数

// when 中的分支条件不仅可以是常量,还可以是任意表达式.例如,下面的代码分支条件就是个函数.
var k = 5
when (k) {getValue(2) -> println("满足条件")getValue(4) -> println("不满足条件")else -> println("条件未知")
}
private fun getValue(num: Int): Int {return num * num
}

for循环

Kotlin 中, for 循环可以直接枚举集合中的元素,也可以按集合索引来枚举元素。

var list = arrayListOf(1, 2, 3, 4, 5)
// 下面的语法是使用迭代器( iterator )枚举集合中的所有元素。
for (i in list) println("for 循环使用迭代器打印集合信息:$i")
var arr = intArrayOf(6, 7, 8, 9, 10)
for (i: Int in arr) println("for 循环使用迭代器打印数组信息:$i")
// 使用索引枚举数组中的元素值。
for (i in list.indices) {println("使用索引值枚举元素值list[$i]=${list[i]}")
}
// 也可以简写为下面这样
for ((index, value) in list.withIndex()) println("使用简写方式索引值枚举元素值list[$index]=$value")

while循环

Kotlin 中的 while 循环和 Java 中的 while 循环是一样的,也分为 while 、do … while

var i = 0
while (i++ < 10) println("while 循环,i = $i")
do {if (i % 3 == 0)println("do while 循环 i = $i")if (i == 6)continueprintln(i)if (i == 5)break
} while (--i > 0)

dowhile 循环中使用了 continuebreak ,这两个语句在 for 循环中同样可以使用。continue 是为了忽略当前循环 continue 后面的所有语旬,继续从下一次循环开始。 break 是为了终结当前循环,并跳出循环。这一点和Java 完全一样。

Kotlin学习(一):Kotlin基础知识相关推荐

  1. Kotlin搞起来——2.基础知识

    在上一节中简单的给大家介绍了下Kotlin的特点,以及结合自己实际项目 中的使用来帮助大家了解这门语言,其实真的没你想象中的那么难,本文打算 介绍的是Kotlin中基础相关的一些语法(用法),有个大概 ...

  2. Kotlin学习——了解Kotlin

    Kotlin学习--了解Kotlin Kotlin的历史 Kotlin是由JetBrains公司开发设计(就是制作IDEA,与PYCharm等顶级IDE的公司) Kotlin2011年公布第一版,20 ...

  3. JNI学习开始篇 基础知识 数据映射及学习资料收集

    JNI学习开始篇 基础知识 数据映射及学习资料收集 JNI介绍 JNI(Java Native Interface) ,Java本地接口. 用Java去调用其他语言编写的程序,比如C或C++. JNI ...

  4. OpenCV与图像处理学习一——图像基础知识、读入、显示、保存图像、灰度转化、通道分离与合并

    OpenCV与图像处理学习一--图像基础知识.读入.显示.保存图像.灰度转化.通道分离与合并 一.图像基础知识 1.1 数字图像的概念 1.2 数字图像的应用 1.3 OpenCV介绍 二.图像属性 ...

  5. php基础教学笔记,php学习笔记:基础知识

    php学习笔记:基础知识 2.每行结尾不允许有多余的空格 3.确保文件的命名和调用大小写一致,是由于类Unix系统上面,对大小写是敏感的 4.方法名只允许由字母组成,下划线是不允许的,首字母要小写,其 ...

  6. 计算机网络基础心得体会结尾,学习《计算机网络基础知识》心得体会

    学习<计算机网络基础知识>心得体会 ... 如今已经是信息时代,作为主流信息工具的网络越来越重 要,网络是信息的载体,是人们传递感情的工具.随着信息社会 的不断发展,网络的应用将会更加广泛 ...

  7. 计算机学生要学的基础知识,中小学生应注重学习计算机的基础知识

    "知识爆炸"和"知识老化"这两大问题,不断困扰着现代教育,人们解决这一问题的良方之一,就是加强学生对基础知识的学习.近年来在中国兴起的中小学生学习计算机热,也同 ...

  8. 【学习笔记--FMCW基础知识】

    学习笔记--FMCW基础知识 前言 mmWave测距原理 mmWave区分多个物体 mmWave的距离分辨率(Range Solution) mmWave的最大测量距离 前言 由于工作原因需要了解TI ...

  9. 使用Vue3学习Vue的基础知识

    创建 Vue 应用 vue的安装有多种方式,本文只讨论基础知识,其他安装方式请自行查阅官网 https://v3.cn.vuejs.org/guide/installation.html 本文使用CD ...

  10. Day 01嵌入式学习之Linux基础知识和命令操作

    学习嵌入式开发的随堂笔记 Day 01嵌入式学习之linux基础知识和命令操作 1.英文: read:读,r字母 write:写,w字母 execute:执行,运行,x字母 directory:目录, ...

最新文章

  1. 开发日记-20190606 关键词 闲散度日
  2. inrange函数 python_为什么OpenCV的inRange函数不将我的HSV图像转换成二进制?
  3. httpclient4 中文版帮助文档,最新官方版翻译版(第一章 上)
  4. vc++ List Control控件获得所有选中行的序号
  5. 纽约时代广场广告费才7千元每天,花钱装逼值不值?
  6. C语言中CY位什么时候才能为1_你真的了解C语言中的整型吗?
  7. Centos 7.3 搭建php7,mysql5.7,nginx1.10.1,redis
  8. C++设计模式之Template Method(模板方法模式)
  9. springboot在eclipse实现热部署
  10. Android 柱状图(自定义View)
  11. Modbus转Profinet网关连接英威腾Goodrive200A配置案例
  12. Python---PDF旋转角度
  13. 对时间序列做分段相关性分析(matlab代码)
  14. ZUCC计算机网络 网络层(一)
  15. 基于微信小程序奶茶店在线点单管理系统#毕业设计
  16. 计算机技能大赛 英语,计算机科学与技术学院英语技能大赛圆满结束
  17. 基因测序技术发展历史及一、二、三代测序技术原理和应用
  18. python语言画成圆相切_在python中如何使用循环结构画四个相切的圆
  19. Acrobat如何将PDF拆分为多个文档
  20. 蓝牙基带协议(baseband specification)

热门文章

  1. 够迫履门夹钾灼敛墒套谮姑韩立对墨大夫一年后是否真的信守承诺,很是怀疑,若真是像对方所说
  2. 电脑拓展显示器软件显示不清晰问题
  3. 从摆地摊到全球网商10强
  4. 国家信息安全水平考试NISP一级模拟题(04)
  5. 龙芯杯系统能力竞赛CPU赛道参赛准备
  6. 唐骏:身价10亿不买房 每月12万住宾馆
  7. 取消Outlook脱机工作
  8. 相似图片搜索原理一(ahash—c++实现)
  9. C语言查找奥运五环色的位置
  10. 计算机组成原理算术运算实验报告,《计算机组成原理》实验报告---8位算术逻辑运算实验.doc...