android Kotlin系列:

Kotlin知识归纳(一) —— 基础语法

Kotlin知识归纳(二) —— 让函数更好调用

Kotlin知识归纳(三) —— 顶层成员与扩展

Kotlin知识归纳(四) —— 接口和类

前序

在19年的Google I/O大会上,Kotlin 成为 Android 开发首选语言。而著名的OkHttp 已经开始用 Kotlin 进行重写工作。是时候通过写博客归纳来巩固Kotlin基础知识。

(一)、语法上的变更

  • 创建对象不需要new关键字
  • 语句不需要;结尾,加;也无所谓
  • 变量类型后置,即变量名在前,变量类型在后。例如 str:String
  • 使用 println() 替代 System.out.println()

(二)、定义变量

Kotlin中使用val关键字声明常量(即变量初始化之后不可再次赋值),var关键字声明变量。

变量定义时可以不显示指定类型,编译器会根据其初始化器的类型进行推断。

//自动推断出 `Int` 类型
var daqi = 1
//可以显式地指定变量的类型
val a :String = "daqi"
//如果变量没有初始化器,需要显式地指定它的类型
val c: Int
c = 3
复制代码

当编译器能确保val变量只有唯一一条初始化语句会被执行,可以根据条件对它初始化不同的值。

val daqi:String
var isChange = true
if (isChange){daqi = "1"
}else{daqi = "2"
}
复制代码

val变量的引用自身是不可变的,但是它指向的对象是可变的。

val languages = arrayListOf("Java")
languages.add("Kotlin")
复制代码

var 关键字允许变量改变自己的值,但不能改变自己的类型。

var daqi = 1
//编译不通过
daqi = ""
复制代码

(三)、定义函数 Kotlin 中使用 fun 关键字声明函数。 完整的函数定义:

修饰符(默认public)+ fun + 方法名 + (参数列表) :返回值 {函数体
}
复制代码
public fun daqi(name:String):String {
}
复制代码

表达式函数体

当单个表达式构成完整的函数体时,可以直接去掉 {} 和 return 语句,函数的返回值类型编译器也会自动推断。这种函数就是表达式函数。

fun sum(a: Int, b: Int) = a + b
复制代码

语句和表达式的区别在于:

  • 表达式有值,并且能作为另一个表达式的一部分使用;
  • 语句总是包围着它的代码块中的顶层元素,并且没有自己的值。

在 Java 中,所有的控制结构都是语句。而在 Kotlin 中,除了循环( for, do 和 do/while )以外大多数控制结构都是表达式(例如:if、 when 以及 try 属于表达式)

表达式函数不光用在些简单的单行函数中 ,也可以用在对更复杂的单个表达式求值的函数中。

fun max(a: Int, b: Int ) = if (a > b) a else b
复制代码

无返回值的函数

类似Java的返回值类型为void的函数

fun daqi():Unit{
}
复制代码

可省略Unit类型

fun daqi(){
}
复制代码

(三)、字符串模板

在 Java 中,当需要打印变量描述和其值时,往往如下打印:

String str = "daqi";
System.out.println("str = " + str);
复制代码

Kotlin支持字符串模板,可以在字符串中引用局部变量,但需要在变量名前加上$。表达式会进行静态检查, 如果$引用一个不存在的变量,代码不会编译通过。

val str = "daqi"
printlin("str = $str")
复制代码

$不仅限于引用于简单的变量名称,还可以引用更复杂的表达式。

val daqi = intArrayOf(1,2,3)
println("${daqi[0]}")
复制代码

在$引用的表达式内(即花括号{}中)可以直接嵌套双引号

println("daqi的第一个元素: ${if(daqi.size > 0) daqi[0] else "null"}")
复制代码

当需要打印$符号时,可以对其进行转义,或者利用表达式对其进行打印:

//打印结果为:$str
val str = "daqi"
println("\$str")
println(${'$'}daqi)
复制代码

(四)、类和属性

在java中定义一个简单类:

public class Person{private final String name;public Person(String name){this.name = name;}public String getName(){return name;}
}
复制代码

用Kotlin写的Person类(默认public修饰)

class Person(val name:String)
复制代码

延伸:若想知道Kotlin对应的具体Java实现,可以通过idea的工具,对Kotlin文件进行反编译:

Tools ->Kotlin -> Show Kotlin Bytecode -> 右侧弹出字节码框 ->左上角 Decompile按钮

整体基本和Java类相似,但是该类被定义为final类,即太监类,不可被继承。

setter 和 getter

在Kotlin中,当你声明属性的时候,也就声明了对应的访问器(即get和set)

val属性只有一个getter,var属性既有 getter 和 setter。 声明一个属性的完整语法:

var <propertyName>[: <PropertyType>] [= <property_initializer>][<getter>][<setter>]
复制代码

其中,初始化器,getter 和 setter 都是可选的。如果类型可以从初始化器或者getter 返回值中推断出来,也可以省略。 访问器的默认实现非常简单,即对对应变量的返回和更改。

当需要在值被访问或修改时提供额外的逻辑,可以通过自定义getter和setter

自定义getter

在Kotlin中的实现

class Rectangle(val height:Int,val width:Int){val isSquare:Booleanget(){return height == width}
}
复制代码

对应的Java实现:

自定义setter

在Kotlin中实现:

class Rectangle(val height:Int,val width:Int){var isSquare:Boolean = falseset(value) {field = value}
}
复制代码

在setter方法中,使用特殊的标识符field来访问支持字段(幕后字段)的值。具体幕后字段后面再说。

注意:

Kolin中,名称以is开头的变量。转换成对应的Java get 和 set 方法时,getter不会添加任何的前准,setter名称中的is会被替换成set。

class Person(var isDaqi:Boolean = false
)
复制代码

该对象在Java中的访问器为:

(五)、迭代

Kotlin中 while 和 do-while循环,其语法与Java的基本没区别。

而for循环仅以一种形式存在,和for-each差不多。但用 in 取代了 :

fun iterationArray(args:Array<String>){for (str in args) {}
}
复制代码

for循环还可以遍历区间。区间本质上是两个值之间的间隔。使用..运算符表示区间。

Kotlin中的区间是闭合区间,即结束值也是区间的一部分。而区间默认迭代步长为1。

val oneToTen = 1..10
复制代码

可以通过step关键字修改步长。遍历时,i变量其增长幅度将变为2,即每次迭代时都会自增2。

for(i in 0..100 step 2){
}
复制代码

如果想要一个半闭合区间,即结束值不属于区间的一部分,可以使用until关键字,

val oneToNine = 1 until 10
复制代码

如果需要一个倒序的区间,可以使用downTo关键字

val tenToOne = 10 downTo 1
复制代码

此时,将从10一直递减到1进行循环。downTo表示的区间也是一个闭合区间。

如果想实现普通for循环一样,对数据索引进行循环,可以使用数组的indices变量

for (i in args.indices) {println(args[i])
}
复制代码

(六)、if表达式

在Kotlin中,if是一个表达式,即它会返回一个值。

if的分支为代码块时,最后的表达式将作为该代码块的值:

val max = if (a > b) {print("Choose a")a
} else {print("Choose b")b
}
复制代码

(七)、when表达式

Kotlin中的when,对应的是Java中的switch,但比起更加强大。

when 将它的参数与所有的分支条件按顺序比较,直到某个分支满足条件,执行其分支对应的代码。当多分支需要用相同的方式处理时,可以把其放在一起,用逗号分隔。

当when作为表达式使用时,必须有 else 分支, 除非编译器检测出所有的可能情况都已经被覆盖。(例如枚举类)

when (x) {0, 1 -> print("x == 0 or x == 1")2 -> print("x == 2")else -> print("otherwise")
}
复制代码

有没有发现,没有了那繁琐的case和break!!

when的参数可有可无,并且无限制类型!而且可以用任意表达式作为分支条件。(switch要求必须使用常量作为分支条件~)

when作为表达式函数的的函数体,直接使用函数的参数,自身并无设置参数。并在条件语句中使用in或者!in 判断一个变量是否在区间或者集合中。

fun daqi(num:Int,intArray: IntArray) = when{num in 1..10 -> "1~10"num !in intArray -> "no in Array"else -> "other"
}
复制代码

when 也可以用来取代 if-else if链.

fun daqi(num:Int) = when{num < 0 -> "小于0"num >0 && num < 10 -> "1..10"else -> "other"
}
复制代码

is可以检查一个变量是否是某种类型,再配合智能转换(检查过某个变量的类型后,不再需要再转换它,直接可以把它当作检查过的类型使用)可以很方便的对进行类型安全操作。

//Any类似于Java的Object
fun daqi(num:Any) = when(num){is String -> {//此时num已经为String类型println("该变量类型为String,获取其长度")println(num.length)}is Int -> {//此时num已经为Int类型println("该变量类型为Int,将其与10进行对比")num.rangeTo(10)}else -> "other"
}
复制代码

(八)、Kotlin中的异常

Kotlin的异常处理与Java类似。当抛出异常时,不需要使用new关键字创建异常实例。

var daqi:String? = null
if (daqi == null){throw NullPointerException("daqi is null")
}
复制代码

try也可以作为表达式,将其赋值给变量。当代码执行正常,则try代码块中最后一个表达式作为结果,如果捕获到异常,对应catch代码块中最后一个表达式作为结果。finally 块中的内容不会影响表达式的结果。

fun readNumber(reader:BufferedReader):Int? = try{Integer.parseInt(reader.readLine())
}catch(e:NumberFormatException){null
}catch (e:NullPointerException){null
}finally {reader.close()
}
复制代码

可以有0到多个 catch 块。finally 块可以省略。 但是 catch 与 finally 块至少应该存在一个。

(九)、枚举

kotlin中用两个关键字enum和class声明枚举类。enum是一个软关键字,只有当它出现在class前面时才有特殊的意义。

声明普通枚举类:

enum class Color{RED,BLUE
}
复制代码

声明带属性的枚举类:

enum class Color(val r:Int,val g:Int,val b:Int){RED(255,0,0),BLUE(0,0,255);fun rgb = (r * 256 + g) * 256 + b
}
复制代码

如果在枚举类型中定义任何方法,需要使用分号;把枚举常量列表和方法定义分开。

参考文献:

  • 《Kotlin实战》
  • Kotlin官网

转载于:https://juejin.im/post/5cebe1526fb9a07f050a479d

Kotlin知识归纳(一) —— 基础语法相关推荐

  1. Kotlin知识归纳(四) —— 接口和类

    android Kotlin系列: Kotlin知识归纳(一) -- 基础语法 Kotlin知识归纳(二) -- 让函数更好调用 Kotlin知识归纳(三) -- 顶层成员与扩展 Kotlin知识归纳 ...

  2. Kotlin快速入门:基础语法、类与继承、集合

    参考书籍: <AtomicKotlin>,全英文,读起来慢,但是写得很详细,没有任何语言基础的也能看懂 <第一行代码 Android 第三版>,第二章,有java基础的看一看就 ...

  3. 【Vue.js 知识量化】基础语法

    Vue.js 基础语法 Vue.js 安装 插值操作 Mustache​:将 data 中的文本数据插入到 HTML v-once:使元素和组件只渲染一次 v-html:解析 HTML 并展示 v-t ...

  4. Python基础知识:python基础语法

    文章目录 前言 一.注释 1.单行注释 2.多行注释 二.缩进 三.关键字 四.变量 1.变量名命名规则 2.赋值语句 五.多行语句 1.语句续行符号 2.语句分隔符号 六.输入与输出 1.输入 2. ...

  5. kotlin读书笔记之基础语法

    1.初识Kotlin 1.1 变量 变量的定义写法上和java差别挺大的.变量分为可读以及可读可写,而且kotlin会自动推测出变量的类型,可推测的情况下. val a: Int = 1 // 立即赋 ...

  6. 猿创征文 | Java知识【Java基础语法】

    目录 1,注释 1.1:使用的技巧 1.2:注意点 2,关键字 2.1:概念 2.2:第一个关键字class 3,字面量 4,变量 4.1:什么是变量? 4.2:变量的定义格式 4.2.1:格式详解 ...

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

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

  8. Kotlin 开篇之基础语法篇

    文章目录 前言 Kotlin 基础 1. 函数声明 1.1 表达式函数体 1.2 函数调用 2. 变量 2.1 可变变量和不可变量 2.2 引用变量值 2.3 空安全 3. 基础类型 3.1 数字类型 ...

  9. python基础语法及知识总结-Python 学习完基础语法知识后,如何进一步提高?

    ---4.30更新---感谢大家支持,点赞都破两千了.给大家整理出来新的资料,需要的小伙伴来自取: Python练手项目视频如下: Python自学基础知识如下: 以下为原文内容: Python 学习 ...

最新文章

  1. java中的类修饰符、成员变量修饰符、方法修饰符。
  2. 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
  3. golang context 父子任务同步取消信号 协程调度 简介
  4. css元素捕捉,css元素选择器
  5. 6种常见的Git错误以及解决的办法
  6. python param_Python基于paramunittest模块实现excl参数化
  7. 关于SAP Commerce Cloud OCC API url里不包含user信息的问题
  8. P7324-[WC2021]表达式求值【dp】
  9. sscanf与正则表达式
  10. (原创)3.2 AddOwner和OverrideMetadata的区别
  11. 外卖匹配系统_歧视外卖员的北京SKP是个什么东西?
  12. easyui combotree 数据太多 无法显示的处理方法
  13. UnityShader32:PBR(一)
  14. read()/write()的生命旅程之三——第三章:write()
  15. 使用SuperWebSocket实现Web消息推送
  16. 广告学计算机平面设计(1)形考5,精编国家开放大学电大专科《计算机平面设计》网络课形考任务1答案.docx...
  17. python电化学cv曲线怎么画_cv曲线(电化学cv曲线分析)
  18. 读了下神书 Introduction to Linear Optimization
  19. 基于区块链的隐私保护与访问控制云框架
  20. 计算机打印步骤,如何将打印机连接到计算机将打印机连接到计算机的步骤[图形教程]...

热门文章

  1. 三菱PLC项目案例学习之PLC控制伺服或步进电机带动丝运行
  2. Grafana的Worldmap插件使用方法
  3. flex垂直居中,最简单的方法之一
  4. Redis高并发问题的解决
  5. 51单片机笔记:中断系统
  6. “国航”助飞旅日华侨华人子女说中文的梦想
  7. CarPlay wired(USB)连接方案
  8. 加密办公文档:保护本地文件
  9. 梅科尔工作室-马欢欢-鸿蒙笔记4
  10. 【ASTRA 3D的配置】