Kotlin语法基础篇一:基本数据类型

508 阅读5分钟

前言

不知道大家有没有和我一样的感受,Android开发已经不再是像15年刚工作那会了,只要把Activity的启动模式说明白了就能找到工作。行业对技术的要求越来越高,对学历的要求也越来越高。基础知识不好,更是不好找工作,Boss上每天更新的Android岗位寥寥无几,简历投了一份又一份,HR都是已读不回。对自己未来的职业生涯也是感到担忧。
随着Google对Android技术的不断更新,Android开发的主流语言也从Java转到了Kotlin。很多企业对Kotlin的要求也越来越高。对于笔者自己而言也是感同身受,没有一个好学历,技术好可能也不会有太好的前景。但是作为一名Andorid开发人员,我们对行业的技术追求不能止步于此。在自己熟悉的行业深耕,总比放弃当下,去接收新的行业强,毕竟Android还没到根本无法就业的惨象。反而我觉得我们在处于劣势的时候更应该把基础打牢,把技术知识学的更深透。让我们从Kotlin的基础开始学起,由浅到深。希望能在这个行业能取得更好的发展。这篇文章给大家带来Kotlin中的基础知识基本数据类型:

1.整型

和Java一样,对于整型Kotlin提供了四种不同的类型,具体的取值范围如下图:

类型大小(比特数)最小值最大值
Byte8-128127
Short16-3276832768
Int32-2,147,483,6482,147,483,648
Long64-9,223,372,036,854,775,8089,223,372,036,854,775,808

(比特数)bit表示计算机内部最小数据存储单位,表示二进制位。
(字节数)Byte是计算机处理数据的基本单位。
一个字节等于八个比特位, 具体转换关系如下:

1Byte   ==  8bit
1Short  ==  2byte  ==  16bit
1Int    ==  4byte  ==  32bit
1Long   ==  8byte  ==  64bit

若声明的整型值未超出Int整型的最大值则会默认推断为Int类型,若超出Int整型的最大值则推断为Long类型。如果需要显示指明Long类型,则在该值后添加L。

val field = 1       // Int
val fieldLong = 1L  // Long

2.浮点数

对于浮点数,Kotlin 提供了 Float 与 Double 类型。根据 IEEE 754 标准, 两种浮点类型的十进制位数(即可以存储多少位十进制数)不同。 Float 反映了 IEEE 754 单精度,而 Double 提供了双精度

类型大小(比特数)有效数字比特数指数比特数十进制数
Float322486-7
Double64531115-16

对于以小数初始化的变量,编译器会推断为 Double 类型。 如需将一个值显式指定为 Float 类型,请添加 f 或 F 后缀。 如果这样的值包含多于 6~7 位十进制数,那么会将其舍入。

val d = 3.14          // Double
val e = 2.7182818284  // Double
val f = 2.7182818284f // Float,实际值为 2.7182817

3.字符

在Kotlin中字符用Char类型表示。声明字符字面值即''单引号中的内容时需要用英文单引号括起来,如下代码示例:

val char = 'c'

特殊字符可以用反斜杠转义。 支持这几个转义序列:\t、 \b\n\r'"\ 与 $。 编码其他字符要用 Unicode 转义序列语法:'\uFF00'

val t = '\t' //水平制表(HT) (跳到下一个TAB位置)
val b = '\b' //退格(BS) ,将当前位置移到前一列
val n = '\n' //换行(LF) ,将当前位置移到下一行开头
val r = '\r' //回车(CR) ,将当前位置移到本行开头

val char1 = '\'' //代表一个单引号(撇号)字符
val char2 = '\"' //代表一个双引号字符
val char3 = '\\' //代表一个反斜线字符''\'
val char4 = '\$' //美元符号($)和花括号({})一起使用,一般用于表示变量或者表达式

字符也可以转换为整型或浮点型。

val numInt = '0'.toInt()
val numFloat = '0'.toFloat()

4.布尔

布尔用 Boolean 类型表示,它有两个值:true 与 false。若需要可空引用布尔会被装箱。

val isActive: Boolean = false

内置的布尔运算有:

  • || – 短路逻辑或
  • && – 短路逻辑与
  • ! - 逻辑非

5.字面常量

二进制:0b00001010。 以0b开头是一种逢2进1的进位制
八进制:Kotlin目前还不支持。
十进制:123。通常用数字0、1、2、3、4、5、6、7、8、9表示,若要声明为 Long 类型用大写L标记:123L。是一种逢10进1的进位制
十六进制:0x0F。通常用数字0、1、2、3、4、5、6、7、8、9和字母A、B、C、D、E、F(a、b、c、d、e、f)表示,其中:A-F表示10-15,是一种逢16进1的进位制
自kotlin1.1起可以在数字字面值中添加下划线,使数字常量更易读。

val integer = 123_456_789
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

6.位运算

对于位运算,没有特殊字符来表示,而只可用中缀方式调用具名函数(关于中缀函数后续的文章会讲解到),如下示例:

val a = (1 shl 2) and 0x000FF000

完整的位运算列表如下(只用于 Int 与 Long): 

位运算符KotlinJava
有符号左移shl(bits)>>
有符号右移shr(bits)<<
无符号右移ushr(bits)>>>
and(bits)&
or(bits)I
异或xor(bits)^
位非(取反运算符)inv() ~

7.装箱和拆箱

关于装箱和拆箱,我们首先来看下Java中的定义:装箱和拆箱是指发生在基本类型与包装类型之间的转换。 

  • 装箱,指基础类型(int、double等)转换成包装类型(Integer、Double等)的过程
  • 拆箱,顾名思义同装箱相反,是从包装类型转换到基础类型的过程。
// Java示例
int a = 10;
Integer b = a; //装箱
int c = b;     //拆箱

而在Kotlin中只存在基本数据类型的装箱过程,并不存在拆箱。 因为Kotlin中并没有像Java中一样的基本数据类型包装类,在Kotlin中是万般皆对象的原则。
在Kotlin中要了解装箱操作,首先要理解可空引用的概念。如果你想明确的声明某个类型是可空的对象,只需要在该类型后面添加 ? 即可。具体语法如下示例:

Int?

String?

ClassName?

val numValue: Int = 123
//装箱的过程,其实装箱之后其值是没有变化的
val numValueBox: Int? = numValue

8.显示转换

Kotlin中的基本数据类型较小的类型并不是较大类型的子类,较小的类型并不能隐式的转换为较大的类型。

val b:Byte = 0  //正确
val i:Int  = b  //错误

Byte类型的引用b并不能直接赋值给Int类型,但是我们可以进行显示的转换。

val b:Byte = 0         //正确
val i:Int  = b.toInt() //正确

在Kotlin中每个数字类型支持如下的转换:

  • toByte(): Byte
  • toShort(): Short
  • toInt(): Int
  • toLong(): Long
  • toFloat(): Float
  • toDouble(): Double
  • toChar(): Char

9.运算

Kotlin支持数字运算的标准集(+ - * / %),运算被定义为相应的类成员(但编译器会将函数调用优化为相应的指令)。 参见运算符重载

10.整数除法 

请注意,整数间的除法总是返回整数。会丢弃任何小数部分。例如:

val x = 5 / 2
//println(x == 2.5) // ERROR: Operator '==' cannot be applied to 'Int' and 'Double'
println(x == 2)     // true

对于任何两个整数类型之间的除法来说都是如此。

val x = 5L / 2
println(x == 2L) // true

如需返回浮点类型,请将其中的一个参数显式转换为浮点类型。

fun main() {
    val result = 5 / 2.0
    println("x = $result")
}

// 输出
x = 2.5

11.数组

数组在 Kotlin 中使用 Array 类来表示,它定义了 get 与 set 函数(按照运算符重载约定这会转变为 [])以及 size 属性,以及一些其他有用的成员函数:

public class Array<T> {
    public inline constructor(size: Int, init: (Int) -> T)

    public operator fun get(index: Int): T

    public operator fun set(index: Int, value: T): Unit

    public val size: Int

    public operator fun iterator(): Iterator<T>
}

可以使用Array类自带的次构造函数,创建一个指定大小,每个元素都相同的数组。

//init是函数类型的参数,后面的文章会详细说明
public inline constructor(size: Int, init: (Int) -> T)

也可以使用Library.kt文件中的顶层函数,arrayOf(vararg: element T) 来创建一个数组并传递元素值给它,这样 arrayOf(1, 2, 3) 创建了 array [1, 2, 3]。 或者,库函数 arrayOfNulls(size: Int) 可以用于创建一个指定大小的、所有元素都为空的数组。

fun main() {
    val arrayString = Array<String>(2) { "a" }
    arrayString.onEach { element -> println(element) }

    val array = arrayOf(1, 2)
    array.onEach { element -> println(element) }

    val nullArray = arrayOfNulls<Int>(2)
    nullArray.onEach { element -> println(element) }
}

// 日志输出
a
a
1
2
null
null

12.原生类型的数组

Kotlin 也有无装箱开销的专门的类来表示原生类型数组: ByteArray、 ShortArrayIntArray 等等。这些类与 Array 并没有继承关系,但是它们有同样的方法属性集。它们也都有相应的工厂方法:

val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]

// 大小为 5、值为 [0, 0, 0, 0, 0] 的整型数组
val arr = IntArray(5)

// 例如:用常量初始化数组中的值
// 大小为 5、值为 [42, 42, 42, 42, 42] 的整型数组
val arr = IntArray(5) { 42 }

// 例如:使用 lambda 表达式初始化数组中的值
// 大小为 5、值为 [0, 1, 2, 3, 4] 的整型数组(值初始化为其索引值)
var arr = IntArray(5) { it * 1 }

13.字符串

Kotlin中用String来表示字符串。字符串是不可变的。 字符串中的元素——字符可以使用索引运算符访问: s[i]。 可以用 for 循环迭代字符串:

fun main() {
    val str = "kotlin"
    for (char in str) {
        print(char)
    }
}

// 日志输出
kotlin

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

fun main() {
    val num = 1_000_0
    println("i = $num") //输出 i = 10000
}

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

fun main() {
    val str = "kotlin"
    println("str = ${str.length}") // 输出 str = 6
}

 总结:

基础知识的学习往往是容易被忽略的,但正是这些基础知识的支撑,才让编程世界的大厦稳健升起。到这里,关于基本数据类型的讲解就结束了。我们下期再见~