阅读 352

Kotlin 系列(二) 基本语法(1)

属性与变量

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 = 18
    var address: String = "北京"

    //定义带参数构造函数
    constructor(name: String, age: Int, address: String) {
        this.name = name
        this.age = age
        this.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+b
    println("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 null
    val 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 的基本语法。

关注下面的标签,发现更多相似文章
评论