End

Kotlin 朱涛-1 基础语法 变量 类型 函数 流程控制

本文地址


目录

01 | Kotlin基础语法:正式开启学习之旅

开发环境

推荐安装 IntelliJ IDEA,可以通过 File -> Project Structure -> SDKs -> + 选择第三方提供的 OpenJDK 。

变量

Kotlin 当中应尽可能避免使用 var(可变变量),尽可能多地使用 val(不可变变量),它相当于 Java 里面的 final 变量

基础类型

基础类型包括数字类型、布尔类型、字符类型,以及这些类型组成的数组

一切皆对象

Java 的类型系统并不是完全面向对象的,因为它存在原始类型,而原始类型并不属于对象。

  • 原始类型(Primitive Types):开销小、性能高,但不是对象
  • 包装类型(Wrapper Type):开销大、性能差,但它是对象,可以很好地发挥面向对象的特性

而 Kotlin 从语言设计的层面上就规避了这个问题,类型系统是完全面向对象的,Kotlin 中没有原始类型这个概念。在 Kotlin 里,一切皆对象。

val i: Double = 1.toDouble() // 1 是对象,所以可以调用它的成员方法

空安全

Kotlin 强制要求开发者在定义变量的时候,指定这个变量是否可能为 null。可为空的变量无法直接赋值给不可为空的变量

数字类型

Kotlin 和 Java 的数字类型基本是一致的,包括它们对数字字面量的定义方式。

val int = 1             // 整数默认会被推导为 Int 类型
val long = 1234567L     // 需要使用 L 后缀
val double = 13.14      // 小数默认会被推导为 Double
val float = 13.14F      // 需要使用 F 后缀
val hexadecimal = 0xAF  // 使用 0x 来代表十六进制字面量
val binary = 0b01010101 // 使用 0b 来代表二进制字面量

Java 可以隐式转换数字类型,而 Kotlin 必须显式转换数字类型。

目的是,让我们代码的可读性更强,将来也更容易维护。

int i = 100;
long j = i;  // 在 Java 中,可以直接把 int 类型赋值给 long 类型,编译器会自动做类型转换
val i = 100
val j: Long = i          // 编译器报错!在 Kotlin 里,必须显式转换
val j: Long = i.toLong() // 编译通过

布尔类型 Boolean

Kotlin 中布尔类型的变量只有两种值,分别是 true 和 false。布尔类型支持与或非逻辑操作。

val isTrue: Boolean = true

字符类型 Char

Char 用于代表单个的字符,比如'A'、'B'、'C',字符用单引号括起来。

val c: Char  =  'A'
val i: Int  = c         // 编译器报错,不支持数字类型隐式转换
val i: Int  = c.toInt() // 编译通过

字符串 String

和 Java 一样,Kotlin 中的字符串也是不可变的。Kotlin 中可以使用字符串模板

val name = "Kotlin"
print("Hello $name!")      // 直接在字符串中访问变量
print("Hello ${name}xxx!") // 有时需要使用花括号将变量括起来

Kotlin 中可以用三个双引号来表示一个原始字符串,用于存放复杂的多行文本。

val s = """
       当我们的字符串有复杂的格式时,
原始字符串非常的方便,
   因为它可以做到所见即所得。 
"""
print(s)

数组

  • 在 Kotlin 当中,一般使用 arrayOf() 来创建数组,同时,Kotlin 编译器也会根据传入的参数进行类型推导
  • Java 中的数组和集合的操作是不一样的,而 Kotlin 中是统一的
val arrayInt = arrayOf(1, 2, 3)             // 类型会被推导为整型数组
val arrayString = arrayOf("apple", "pear")  // 类型会被推导为字符串数组

函数

函数声明 fun

//关键字  函数名         参数类型  返回值类型
//↓        ↓               ↓        ↓
fun helloFunction(name: String): String {
    return "Hello $name !"
}

单一表达式函数

函数体只有一行代码

  • 可以省略函数体的花括号,直接使用=来连接
  • 表达式中的return需要去掉
  • 返回值的类型也可以省略
fun helloFunction(name: String) = "Hello $name !"

函数调用

Kotlin 支持命名参数,它允许我们在调用函数的时候传入形参的名字,这样的代码可读性更强。

helloFunction("Kotlin")
helloFunction(name = "Kotlin")  // 只能是形参的名字 name

Kotlin 支持参数默认值,在参数较多的情况下有很大的优势。

fun createUser(
        name: String,
        age: Int,
        count: Long = 0L,
        size: Int = 0,
) = println("name=$name age=$age count=$count size=$size")

createUser("bqt", 30)
createUser("bqt", 30, 10) // name=bqt age=30 count=10 size=0
createUser(age = 30, size = 10, name = "bqt")

流程控制

在 Kotlin 当中,流程控制主要有 if、when、for、 while。

if

Kotlin 中的 if,除了可以作为程序语句(Statement),它还可以作为表达式(Expression)来使用。

val i = 1
val message = if (i > 0) "Big" else "Small"

var text: String? = null
val i = if (text != null) text.length else 0

val j = text?.length ?: 0  // Elvis 表达式

when

类似 Java 里的 switch case 语句。

val i: Int = 1
when(i) {
    1 -> print("一")
    2 -> print("二")
    else -> print("不是一也不是二")
}

when 也可以作为表达式,为变量赋值。此时要求它里面的逻辑分支必须是完整的

val i: Int = 1
val message = when(i) {
    1 -> "一"
    2 -> "二"
    else -> "i 不是一也不是二" // 如果去掉这行,会报错
}

while 与 for

Kotlin 的 for 语句更多的是用于迭代数组、集合、区间。

val array = arrayOf(1, 2, 3)
for (i in array) {}

val oneToThree = 1..3  // 代表 [1, 3],不能定义【逆序区间】
for (i in oneToThree) {}

val reverse = 6 downTo 0 step 2  // 步长为 2 的逆序区间,即 6 4 2 0

注意,逆序区间需要使用 downTo 来定义,使用 .. 定义的逆序区间无法遍历到任何元素。

小结

让开发者写出简洁易懂的代码:

  • 支持类型推导
  • 代码末尾不需要分号
  • 字符串模板
  • 原始字符串
  • 单一表达式函数
  • 函数参数支持默认值
  • if 和 when 可以作为表达式

在语言设计的层面规避错误

  • 强制区分可为空类型不可为空类型,规避空指针异常
  • 推崇不可变性,
  • 基础类型不支持隐式类型转换,避免隐藏问题
  • 数组访问行为与集合统一
  • 函数调用支持命名参数,提高可读性
  • when 表达式强制要求逻辑分支完整,避免逻辑漏洞

2018-02-11

posted @ 2018-02-11 17:13  白乾涛  阅读(954)  评论(0编辑  收藏  举报