属性与变量

Kotlin 类中的属性,既可以使用关键字 var 声明为可变的,也可以用 val 声明为只能赋值一次的只读变量。

变量

/**
*只读变量
*/
val a: Int = 1 //立即赋值val b = 30 //自动推断出 Int 类型val c = "hello" //自动推断出 String 类型
/**
*可变变量
*/
var name: String = "keven" //立即赋值var age: Int = 18 //立即赋值var address: String = "北京" //立即赋值
复制代码

Kotlin 中使用关键字 class 声明类

class Person { }
复制代码
构造函数

在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。主构造函数是类头的一部分:它跟在类名(与可选的类型参数)后。

class Person constructor(firstName: String) {}
复制代码

如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。

class Person(firstName: String) {
}
复制代码

也可以在类中定义次构造函数

class Person {//定义一些可变变量var name: String = "keven"var age: Int = 18var address: String = "北京"//定义带参数构造函数constructor(name: String, age: Int, address: String) {this.name = namethis.age = agethis.address = address}//无参构造函数constructor()}
复制代码

使用 Person 类

//Kotlin 中没有 new 关键字
var result = Person()  //使用无参构造函数
result.name = "KEVEN"  //给变量赋值
result.age = 19
result.address = "上海"//使用有参构造函数
var person=Person("Keven",20,"深圳")
复制代码

函数

Kotlin 中的函数使用 fun 关键字声明

1. 定义带参函数

注意:如果一个函数不返回任何有用的值,它的返回类型是 Unit。Unit 是一种只有一个值 Unit 的类型。这个值不需要显式返回

//带有两个 Int 参数
//$a $b $c 代表引用 a、b、c 的值
fun printSum(a: Int, b: Int) {var c=a+bprintln("sum of $a and $b is $c")
}
复制代码

2. 定义带参数、带返回值的函数

//带有两个 Int 类型参数,返回值为 Int 类型
fun Sum(a: Int, b: Int): Int {return a + b
}
复制代码

3.单表达式函数

将表达式作为函数体,返回值类型自动推断的函数

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

4. 定义参数有默认值的函数

//其中 Boolean 类型参数 isMale 默认值为 true
//其中 Char 类型参数 short 默认值为 'a'
fun reformat(name: String, isMale: Boolean = true, short: Char = 'a') {}//调用有默认值参数的函数时,可不传有默认值的参数
reformat("CUE")
//当然也可以全传递
reformat("CUE",true,'C')
复制代码

5. 可变数量参数的函数

函数的参数(通常是最后一个)可以用 vararg 修饰符标记

//使用 vararg 进行参数修饰
fun asList(vararg list: Int) {for (a in list)println("a = $a")
}
复制代码

对于可变参数函数进行调用

//传入任意个数 Int 类型参数
asList(1, 2, 3, 4)asList(0, 1, 2)
复制代码

字符串模板

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

val i = 10
println("i = $i") // 输出“i = 10”
复制代码

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

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

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

val price = """${'$'}9.99"""
println(price)//输出“$9.99”
复制代码

if 表达式

在 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
复制代码

if 的分支可以是代码块,最后的表达式作为该块的值

//输出 a、b 中较大的一项
var a = 1
var b = 2
val max = if (a > b) {a
} else {b
}
复制代码

使用可空值及 null 检测

许多编程语言(包括 Java)中最常见的陷阱之一,就是访问空引用的成员会导致空引用异常。在 Java 中,这等同于 NullPointerException 或简称 NPE。

Kotlin 的类型系统旨在从我们的代码中消除 NullPointerException。

使用

在 Kotlin 中,类型系统区分一个引用可以容纳 null (可空引用)还是不能容纳(非空引用)。 例如,String 类型的常规变量不能容纳 null:

var a: String = "abc"
a = null // 编译错误
复制代码

如果要允许为空,我们可以声明一个变量为可空字符串,写作 String?:

var b: String? = "abc"
b = null // ok
print(b)
复制代码

检测

val b: String? = "Kotlin"
if (b != null && b.length > 0) {print("String of length ${b.length}")
} else {print("Empty string")
}
复制代码

这只适用于 b 是不可变的情况(即在检查和使用之间没有修改过的局部变量 ,或者不可覆盖并且有幕后字段的 val 成员),因为否则可能会发生在检查之后 b 又变为 null 的情况。

安全的调用

安全调用操作符,写作 ?.:

val a = "Kotlin"
val b: String? = null
println(b?.length)
println(a?.length) // 无需安全调用
复制代码

如果 b 非空,就返回 b.length,否则返回 null,这个表达式的类型是 Int?。

安全调用在链式调用中很有用。例如,如果一个员工 Bob 可能会(或者不会)分配给一个部门, 并且可能有另外一个员工是该部门的负责人,那么获取 Bob 所在部门负责人(如果有的话)的名字,我们写作:

bob?.department?.head?.name
复制代码

如果任意一个属性(环节)为空,这个链式调用就会返回 null。

如果要只对非空值执行某个操作,安全调用操作符可以与 let 一起使用:

val listWithNulls: List<String?> = listOf("Kotlin", null)
for (item in listWithNulls) {item?.let { println(it) } // 输出 Kotlin 并忽略 null
}
复制代码

安全调用也可以出现在赋值的左侧。这样,如果调用链中的任何一个接收者为空都会跳过赋值,而右侧的表达式根本不会求值:

// 如果 `person` 或者 `person.department` 其中之一为空,都不会调用该函数:
person?.department?.head = managersPool.getManager()
复制代码

Elvis 操作符

判断如果 b 不为 null ,返回 b 的长度,否则返回 -1

val l: Int = if (b != null) b.length else -1
复制代码

除了完整的 if-表达式,这还可以通过 Elvis 操作符表达,写作 ?:

val l = b?.length ?: -1
复制代码

如果 ?: 左侧表达式非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式。 请注意,当且仅当左侧为空时,才会对右侧表达式求值。

请注意,因为 throw 和 return 在 Kotlin 中都是表达式,所以它们也可以用在 elvis 操作符右侧。这可能会非常方便,例如,检查函数参数:

fun foo(node: Node): String? {val parent = node.getParent() ?: return nullval name = node.getName() ?: throw IllegalArgumentException("name expected")// ……
}
复制代码

安全的类型转换

如果对象不是目标类型,那么常规类型转换可能会导致 ClassCastException。 另一个选择是使用安全的类型转换,如果尝试转换不成功则返回 null

val aInt: Int? = a as? Int
复制代码

可空类型的集合

如果你有一个可空类型元素的集合,并且想要过滤非空元素,你可以使用 filterNotNull 来实现

val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()
复制代码

本小节就介绍到这里,下一小节我们会继续学习 Kotlin 的基本语法。

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

Kotlin 系列(二) 基本语法(1)相关推荐

  1. Kotlin系列之基础语法

    标签: Kotlin      Kotlin基础语法 目录: 一.包的声明 二.函数的定义 三.常量和变量 四.注释 五.字符串模板 六.使用条件表达式 七.NULL检查机制 八.类型检测以及自动类型 ...

  2. Kotlin系列二:面向对象编程(类与对象)

    目录 一  类与对象 二 延迟初始化属性与变量 三 继承 四 构造函数 4.1 主构造函数 4.2 次构造函数. 五 接口 六 数据类与单例类 6.1 数据类 6.2 单例类 七 密封类 八 嵌套类与 ...

  3. 学习Kotlin(二)基本语法

    推荐阅读: 学习Kotlin(一)为什么使用Kotlin 学习Kotlin(二)基本语法 学习Kotlin(三)类和接口 学习Kotlin(四)对象与泛型 学习Kotlin(五)函数与Lambda表达 ...

  4. (二十三)Kotlin简单易学 基础语法-什么是函数式编程

    (二十三)Kotlin简单易学 基础语法-什么是函数式编程 什么是函数式编程 我们一直在学习面向对象编程范式,另一个较知名的编程范式是诞生于20世纪50年代,基于抽象数学的λ演算发展而来的函数编程,尽 ...

  5. [译]Effective Kotlin系列之探索高阶函数中inline修饰符(三)

    简述: 不知道是否有小伙伴还记得我们之前的Effective Kotlin翻译系列,之前一直忙于赶时髦研究Kotlin 1.3中的新特性.把此系列耽搁了,赶完时髦了还是得踏实探究本质和基础,从今天开始 ...

  6. Kotlin系列之集合和函数式API完全解析-上篇

    简述: 今天带来的是Kotlin浅谈系列的第八讲,这讲我们一起来聊聊Kotlin这门语言对函数式编程的支持.我们都知道在kotlin这门语言中函数荣升成为了一等公民,所以在支持函数式编程的方面,Kot ...

  7. Kotlin系列之Lambda编译成字节码过程完全解析

    简述: 今天带来的是Kotlin浅谈系列第七弹,上篇博客我们聊到关于Kotlin中的lambda表达式的一些语法规则和基本使用.然而我们并没有聊到Kotlin的lambda表达式的本质是什么?我们都知 ...

  8. [译]Effective Kotlin系列之考虑使用原始类型的数组优化性能(五)

    翻译说明: 原标题: Effective Kotlin: Consider Arrays with primitives for performance critical processing 原文地 ...

  9. Kotlin系列之let、with、run、apply、also函数的使用

    标签: Kotlin      常用技巧 目录: 一.回调函数的Kotin的lambda的简化 二.内联扩展函数之let 三.内联函数之with 四.内联扩展函数之run 五.内联扩展函数之apply ...

  10. openresty开发系列15--lua基础语法4表table和运算符

    openresty开发系列15--lua基础语法4表table和运算符 lua中的表table 一)table (表) Table 类型实现了一种抽象的"关联数组".即可用作数组, ...

最新文章

  1. 第六十一天 how can I 坚持
  2. 在malloc函数中为什么常用sizeof来设定内存分配的大小?
  3. P3964-[TJOI2013]松鼠聚会【计算几何】
  4. 知道的C君带你学语言的作业答案,知到《C君带你玩编程》2020章节测试(含答案)...
  5. 苹果手机黑屏了怎么办_来电话手机黑屏怎么办
  6. 蔡俊锋 web API 开发规范
  7. 图片缩放与目标值的规范
  8. 2006. 差的绝对值为 K 的数对数目
  9. 迷宫问题的通用解法C语言数据结构实现
  10. 脚本——LoadRunner文件操作函数详解
  11. 西铁城手表最外圈数字是什么_有的手表表盘外面有一圈数字,可以转动,是计算什么用的?...
  12. MATLAB R2016b + VS2017专业版安装spams
  13. android开发split的方法在String中的特殊使用
  14. sap 流程图 退货销售订单_销售订单_退货型
  15. 基于Android的高德地图的定位和运动轨迹记录的功能
  16. 什么是EFI系统分区?
  17. 【CPU GPU TPU】机器学习扫盲篇
  18. Cisco CCNP认证642-902题库资讯
  19. 【UnityShader】光线追踪体积光
  20. 用python做模型_Python实现Kuramoto模型的思想前提

热门文章

  1. 手动实现Spring中的IOC容器
  2. EF三种编程方式详细图文教程(C#+EF)之Database First
  3. windows python3.7安装numpy问题的解决方法
  4. python---os
  5. 修改NLS_DATE_FORMAT的四种方式
  6. SPOJ_SUBLEX
  7. java环境json哪些事?
  8. HTC G7 金卡 制作
  9. DVWA--SQL Injection(非盲注)--四个级别
  10. 微信小程序 详解 小程序支付