1 变量

1.1 变量声明

var a : Int // 声明整数类型变量
var b : Int = 1 // 声明整数类型变量, 同时赋初值为1
var c = 1 // 声明整数类型变量, 同时赋初值为1
val d = 1 // 声明整数类型常量, 值为1(后面不能改变d的值)

​ 变量命名规范如下。

  • 变量名可以由字母、数字、下划线(_)和美元符号($)组成,但是不能以数字开头,且大小写敏感。
  • 不能有空格、@、#、+、-、/ 等符号。
  • 应该使用有意义的名称,达到见名知意的目的,最好以小写字母开头。
  • 不能与 Kotlin 语言的关键字或是基本数据类型重名。

1.2 getter 和 setter方法

1.2.1 自定义 getter 和 setter

​ 在全局变量或类的成员变量声明时,会自动生成 getter 或 setter 方法,用户也可以重载这些方法,如下。

var a : Int = 5
    get() {
        println("get, field=$field")
        return field
    }
    set(value) {
        println("set, old-field=$field, new-field=$value")
        field = value
    }
fun main() {
    a // 打印: get, field=5
    a = 10 // 打印: set, old-field=5, new-field=10
}

​ 当 getter 方法只有一行时,可以简写如下。

var a : Int = 5
    get() = field + 15
fun main() {
    println(a) // 打印: 20
}

1.2.2 继承 java 的 getter 和 setter

​ People.java

public class People {
    public String getName() {
        return "zhang san";
    }
    public void setName(String name) {
        System.out.println(name);
    }
}

​ Test.kt

fun main() {
    var stu = Student()
    println(stu.name) // 打印: zhang san
    stu.name = "li si" // 打印: li si
}
class Student : People()

​ 注意:People 中没有 name 属性,但 main 函数中可以通过 stu.name 访问到 People 的 getName 方法;如果 People 使用 Kotlin 语言编写,stu.name 会编译报错。

1.3 空值

1.3.1 T? 和 lateinit

​ 在 Kotlin 中,对空值处理非常严格,正常情况下,变量不能直接赋值为 null,否则会编译报错。如果我们希望某个变量在初始化时赋值为 null,可以在类型名称后面添加一个问号(?)。另外,对于引用类型,如果不想在变量声明时初始化,也可以在 var 前面添加 lateinit 修饰符,表示延时初始化。

fun main() {
    var str1: String
    // var str2: String = null // 编译报错
    var str3: String? = null
    lateinit var str4: String
}
class A {
    // var str1: String // 编译报错
    // var str2: String = null // 编译报错
    var str3: String? = null
    lateinit var str4: String
    // var i1: Int // 编译报错
    // var i2: Int = null // 编译报错
    var i3: Int? = null
    // lateinit var i4: Int // 编译报错(基本数据类型不允许延时初始化)
}

1.3.2 非空断言符(!!.)

​ 非空断言符(!!.)用于告诉编译器:不会出现空指针问题,不用进行空值检查,强制访问点后面的内容。

fun main() {
    var str: String? = null
    // println(str.length) // 编译报错
    println(str!!.length)
}

1.3.3 安全访问符(?.)

​ 安全访问符(?.)用于告诉编译器:如果对象非空才访问点后面的内容,否则不做任何处理。

fun main() {
    var str: String? = null
    // println(str.length) // 编译报错
    println(str?.length) // 打印: null
}

1.3.4 Elvis 运算符(?:)

​ Elvis 运算符(?:)用于告诉编译器:如果 ?: 前面的值为 null,就取 ?: 后面的值。

fun main() {
    var str1: String? = null
    var str2: String = str1 ?: "Hello"
    println(str2) // 打印: Hello
}

2 基本数据类型

2.1 空类型

​ Kotlin 中空类型使用 Unit 表示,等价与 Java 中的 void。

1)Unit 的定义

public object Unit {
    override fun toString() = "kotlin.Unit"
}

2)Unit 作为变量使用

fun main() {
    var a : Unit = Unit
    println(a) // kotlin.Unit
}

3)Unit 作为函数返回值使用

fun myFun() : Unit {
    println("定义一个没有返回值的函数")
}

​ 说明:当函数无返回值时,可以省略 Unit。

2.2 数字类型

2.2.1 整数类型

类型 大小(位) 最小值 最大值 案例
Byte 8 -128 127 var a: Byte = 1 var a = 1 val a = 0b1001 // 二进制 val a = 0xAF // 十六进制
Short 16 -32768 32767 var a: Short = 1 var a = 1
Int 32 -2,147,483,648 (-2^31) 2,147,483,648(2^31-1) var a: Int = 1 var a = 1 var a = 1_000_000
Long 64 -9,223,372,036,854,775,808(-2^63) 9,223,372,036,854,775,807 (2^63-1) var a: Long = 1L var a = 1L
UByte 8 0 255 var a: UByte = 1u var a = 1u
UShort 16 0 65535 var a: UShort = 1u var a = 1u
UInt 32 0 4,294,967,295 (2^32-1) var a: UInt = 1u var a = 1u
ULong 64 0 18,446,744,073,709,551,615 (2^64-1) var a: ULong = 1uL var a = 1uL var a = 0xFFF_FFF_FFFuL

​ 进制表示如下。

// 二进制
val a = 0b1001 // 0b是二进制前缀, 1001对应十进制的9
// 十六进制
val a = 0xAF // 0x是十六进制前缀, AF对应十进制的31

​ 注意:Kotlin 没有八进制前缀表示。

2.2.2 浮点类型

类型 大小(位) 符号位(S)/ 阶码(E)/ 尾数(M) 最小值/ 最大值/ 最小正数 有效位数 案例
Float 32 1S + 8E + 23M -3.4028235E38 3.4028235E38 1.4E-45 6 var a: Float = 1.0F var a = 1.0F var a = 1.0f
Double 64 1S + 11E + 52M -1.7976931348623157E308 1.7976931348623157E308 4.9E-324 15 var a: Double = 1.0 var a = 1.0

​ 浮点数编码原理详见 → 浮点数编码原理

2.2.3 运算符

运算符 描述 作用域 优先级 案例
+ 加法 整数/浮点数 作为一元运算符时,优先级为1 作为二元运算符时,优先级为3 1 + 2 ⇒ 3
减法 整数/浮点数 作为一元运算符时,优先级为1 作为二元运算符时,优先级为3 1 – 2 ⇒ -1
* 乘法 整数/浮点数 2 2 * 3 ⇒ 6
/ 整除/除法 整数/浮点数 2 3 / 2 ⇒ 1 3.0 / 2 ⇒ 1.5 3 / 2.0 ⇒ 1.5
% 取余 整数/浮点数 2 7 % 3 ⇒ 1
++ 加1 整数/浮点数 1 a++(先使用, 后加1) ++a(先加1, 后使用)
减1 整数/浮点数 1 a–(先使用, 后减1) –a(先减1, 后使用)
= 赋值 所有类型 9 a = 1
+= 加赋值 整数/浮点数 9 a += 1 ⇔ a = a + 1
-= 减赋值 整数/浮点数 9 a -= 2 ⇔ a = a – 2
*= 乘赋值 整数/浮点数 9 a *= 3 ⇔ a = a * 3
/= 除赋值 整数/浮点数 9 a /= 4 ⇔ a = a / 4
%= 取余赋值 整数/浮点数 9 a %= 5⇔ a = a % 5
shl 有符号左移 Int/Long 4 3 shl 1 ⇒ 6 -1 shl 1 ⇒ -2 -3 shl 1 ⇒ -6
shr 有符号右移 Int/Long 4 3 shr 1 ⇒ 1 -1 shr 1 ⇒ -1 -3 shr 1 ⇒ -2
ushr 无符号右移 Int/Long 4 3 ushr 1 ⇒ 1 -1 ushr 1 ⇒ 2147483647 -3 ushr 1 ⇒ 2147483646
and 按位与 Int/Long 5 // 1001 and 0011 ⇒ 0001 9 and 3 ⇒ 1
or 按位或 Int/Long 6 // 1001 or 0011 ⇒ 1011 9 or 3 ⇒ 11
xor 按位异或 Int/Long 7 // 1001 xor 0011 ⇒ 1010 9 or 3 ⇒ 10
inv 按位取反 Int/Long 1 9.inv() ⇒ -10 (-1).inv() ⇒ 0 (-3).inv() ⇒ 2
.. 范围 整数 8 1..4 // 1, 2, 3, 4 1..5 step 2 // 1、3、5
..< 范围 整数 8 1..<4 // 1, 2, 3
until 范围 整数 8 1 until 4 // 1, 2, 3
downTo 范围 整数 8 3 downTo 1 // 3、2、1

2.3 布尔类型

2.3.1 布尔类型

类型 大小(位) 取值 案例
Boolean 1 true / false var a: Boolean = true var a = false

2.3.2 运算符

运算符 描述 作用域 优先级 案例
== 等于 整数/布尔/字符 1 1 == 2 // false 1 == 1 // true
!= 不等于 整数/布尔/字符 1 1 != 2 // true 1 != 1 // false
< 小于 整数/浮点数/字符 1 1 < 2 // true
大于 整数/浮点数/字符 1 1 > 2 // false
<= 小于等于 整数/字符 1 1 <= 2 // true
>= 大于等于 整数/字符 1 1 >= 2 // false
in 在范围内 整数/字符 1 3 in 1..9 // true
!in 不在范围内 整数/字符 1 3 !in 1..9 // false
! 布尔 2 !true // false !false // true
&& 布尔 3 true && false // false
|| 布尔 4 true || false // true

2.4 字符类型

2.4.1 字符类型

类型 大小(位) 案例
Char 16 var a: Char = ‘A’ var a = ‘A’ var a = ‘好’ var a = ‘u725B’ // 牛 var a = Char(66) // B var a = ‘A’ + 4 // E ‘A’.code // 65

2.4.2 转义字符

t —— Tab制表符
b —— 退格
n —— 换行(LF)
r —— 回车(CR)
' —— 单引号
" —— 双引号
\ —— 反斜杠
$ —— 美元符号

2.5 字符串类型

2.5.1 字符串的定义

var str1 : String = "abc"
var str2 = "abc"
var str3 = "abc" + "def" // "abcdef"
// 原始字符串
var str4  = """
        第一行
        第二行
        第三行
    """
// 字符串模板
var count = 15
var str5 = "买了${count}个苹果" // 买了15个苹果

​ 通过下标即可访问字符串中元素,如下。

var str = "abc"
var c1 = str[0] // 'a'
var c2 = str.elementAt(1) // 'b'

2.5.2 字符串函数

​ Kotlin 中 String 类继承 CharSequence 类,在 _String.kt、StringsJVM.kt、StringNumberConversionsJVM.kt 等文件中定义了一些 CharSequence、String 的扩展函数。

1)判空

// length == 0
public inline fun CharSequence.isEmpty(): Boolean
// length > 0
public inline fun CharSequence.isNotEmpty(): Boolean
// this == null || this.length == 0
public inline fun CharSequence?.isNullOrEmpty(): Boolean
// length == 0 || indices.all { this[it].isWhitespace() }
public actual fun CharSequence.isBlank(): Boolean
// !isBlank()
public inline fun CharSequence.isNotBlank(): Boolean
// this == null || this.isBlank()
public inline fun CharSequence?.isNullOrBlank(): Boolean

2)去掉首位空字符

public inline fun String.trim(): String

3)查找字符

public expect fun CharSequence.elementAt(index: Int): Char
public inline fun CharSequence.find(predicate: (Char) -> Boolean): Char
public inline fun CharSequence.findLast(predicate: (Char) -> Boolean): Char
public fun CharSequence.first(): Char
public inline fun CharSequence.first(predicate: (Char) -> Boolean): Char
public fun CharSequence.last(): Char
public inline fun CharSequence.last(predicate: (Char) -> Boolean): Char
public inline fun CharSequence.random(): Char

4)查找字符索引

public inline fun CharSequence.indexOfFirst(predicate: (Char) -> Boolean): Int
public inline fun CharSequence.indexOfLast(predicate: (Char) -> Boolean): Int

5)过滤字符

public inline fun String.filter(predicate: (Char) -> Boolean): String
public inline fun String.filterIndexed(predicate: (index: Int, Char) -> Boolean): String
public inline fun String.filterNot(predicate: (Char) -> Boolean): String

6)统计字符个数

// 返回length
public inline fun CharSequence.count(): Int
// 统计字符串中满足条件的字符个数
public inline fun CharSequence.count(predicate: (Char) -> Boolean): Int

7)字符串匹配

// 判断字符串是否以xxx开头
public fun CharSequence.startsWith(char: Char, ignoreCase: Boolean = false): Boolean
public fun CharSequence.startsWith(prefix: CharSequence, ignoreCase: Boolean = false): Boolean
public fun CharSequence.startsWith(prefix: CharSequence, startIndex: Int, ignoreCase: Boolean = false): Boolean
// 判断字符串是否以xxx结尾
public fun CharSequence.endsWith(char: Char, ignoreCase: Boolean = false): Boolean
public fun CharSequence.endsWith(suffix: CharSequence, ignoreCase: Boolean = false): Boolean

8)获取子串

public inline fun CharSequence.substring(startIndex: Int, endIndex: Int = length): String
public fun String.substring(range: IntRange): String
public fun String.slice(indices: IntRange): String
public fun String.take(n: Int): String
public fun String.takeLast(n: Int): String

9)字符串分割

public fun CharSequence.split(vararg delimiters: Char, ignoreCase: Boolean = false, limit: Int = 0): List<String>
public fun CharSequence.split(vararg delimiters: String, ignoreCase: Boolean = false, limit: Int = 0): List<String>

​ 说明:字符串分割支持正则匹配,详见 → 正则表达式(Regular Expression)详解

10)字串替换

// 替换所有匹配的字符或字符串
public actual fun String.replace(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String
public actual fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String
// 替换第一个匹配的字符或字符串
public actual fun String.replaceFirst(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String
public actual fun String.replaceFirst(oldValue: String, newValue: String, ignoreCase: Boolean = false): String
// 将第一个匹配的字符或字符串前面的字符串替换为指定字符或字符串
public fun String.replaceBefore(delimiter: Char, replacement: String, missingDelimiterValue: String = this): String
public fun String.replaceBefore(delimiter: String, replacement: String, missingDelimiterValue: String = this): String
// 将第一个匹配的字符或字符串后面的字符串替换为指定字符或字符串
public fun String.replaceAfter(delimiter: Char, replacement: String, missingDelimiterValue: String = this): String
public fun String.replaceAfter(delimiter: String, replacement: String, missingDelimiterValue: String = this): String
// 将指定索引范围的字符串替换为新字符串
public inline fun String.replaceRange(startIndex: Int, endIndex: Int, replacement: CharSequence): String
public inline fun String.replaceRange(range: IntRange, replacement: CharSequence): String

​ 说明:字符串替换支持正则匹配,详见 → 正则表达式(Regular Expression)详解

11)字符串反转

public inline fun String.reversed(): String

12)大小写转换

// 转为大写字符串, locale可以传入Locale.ROOT
public inline fun String.uppercase(locale: Locale): String
// 转为小写字符串, locale可以传入Locale.ROOT
public inline fun String.lowercase(locale: Locale): String

13)数据类型转换

public actual inline fun String.toInt(): Int
public actual inline fun String.toLong(): Long
public actual inline fun String.toFloat(): Float
public actual inline fun String.toDouble(): Double
public inline fun String.toBigInteger(): java.math.BigInteger
public inline fun String.toBigDecimal(): java.math.BigDecimal

​ 声明:本文转自【Kotlin】变量和基本数据类型