本篇主要介绍 Kotlin 的基础语法,控制流,内建数据类型等内容…
import语句和包的相关概念。可见度修饰符的使用。
大部分内建数据类型的介绍。包括数值类型,字符类型,布尔类型,数组类型,字符串类型。
控制流的使用,
if,when,for,while等关键字在Kotlin中的新特性。如何在函数中返回和跳转,
return,continue,break等关键字的使用。
go~
包
| 1 | // 导包 | 
可见度修饰符
类,对象,接口,构造器,函数,属性以及属性访问器设值方法(访问器取值方法总与属性本身可见度相同,因此不需要控制其可见度),都可以使用 可见度修饰符 。Kotlin 中的四种可见度修饰符:private、protected、internal、public,默认为 public。与 Java 不同的是少了 default 多了 internal。
注意:局部变量, 局部函数,以及局部类,都不能指定可见度修饰符。
top-level
top-level, 像 class 这种可以直接声明在包下。在 Kotlin 中,函数, 属性, 类, 对象, 接口都可以声明为 top-level。比如扩展函数和扩展属性就是 声明为 top-level 的。注意,这里说的是 top-level 级别声明,在这些声明内部再声明别的函数或者属性,不在讨论范畴,将在下一部分说明,对于 top-level 中的声明来说:
public:意为该声明在任何位置都可以访问,public 是默认的,可以省略。If you do not specify any visibility modifier, public is used by default, which means that your declarations will be visible everywhere;
private:意为该声明只能在同一个源代码文件中访问。If you mark a declaration private, it will only be visible inside the file containing the declaration;
internal:意为该声明在同一个module的任意位置是可以访问的。If you mark it internal, it is visible everywhere in the same module;
protected:对top-level的声明是无效的。protected is not available for top-level declarations.
| 1 | package com.march.ktexample | 
类与接口
在类和接口内部使用可见度修饰符
private:在类内(以及它的所有成员之间)可以访问。private means visible inside this class only (including all its members);
protected:和private相同,而且在子类中也可以访问。protected — same as private + visible in subclasses too;
internal:在同一个module内,能访问该类的地方,也能访问该类的internal成员。any client inside this module who sees the declaring class sees its internal members;
public:在任何位置凡是能访问该类,则也能访问该类的public成员。any client who sees the declaring class sees its public members.
注意: 在 Kotlin 中,外部类不能访问其内部类的 private 成员。如果你覆盖一个 protected 成员,并且没有明确指定可见度,那么覆盖后成员的可见度也将是 protected。
| 1 | open class OuterCls { | 
构造器
注意,指定类构造器可见度,你需要明确添加一个 constructor 关键字。
private:表示构造器只在类内可以访问。
protected:类构造器可见度不支持protected。
internal:表示同模块内可以访问该构造器。
public:在任何位置都可访问,构造器默认public。
| 1 | class MyCls1 private constructor(){ | 
内建数据类型
介绍 Kotlin 的内建数据类型,包括数值类型,字符类型,布尔类型,数组类型,字符串类型。
数值类型
Kotlin 数值使用内建对象表示,所有数值类型继承自 Number 抽象类,Number 中定义了数值在各个类型之间转换的方法。
 Long 类型需要在数字末尾追加 大写 的 L 表示,如 123L;Float 类型需要在数字末尾追加 f/F 表示,如 123.5F。默认十进制计数,如: 123;十六进制以 0x 开头,如 0x1FA;二进制以 0b 开头,如 0b001101;不支持 八进制表示。
小数默认是 Double 类型,如果需要显式声明为 Float,需要加 f/F 后缀。
Double (64 bit) ;Float (32 bit) ;Long (64 bit) ;Int (32 bit) ;Short (16 bit) ;Byte (8 bit) ;
同一性:对象的类型,内容相同,使用
===运算符比较为true相等性:内容相等,使用
==运算法比较为true
- 数值装箱
Kotlin 中一切皆为对象,因此内建的数值类型也为对象,但是他们具有如同基本数据类型的特性,即 同一性,数值内建对象就如同 Java 中的基本数据类型,他们的值是不能为 null 的,你可以使用像 Int? 这样来进行数值装箱,这里可以参考 Java 中数值装箱的概念。装箱之后的数值会保持 相等性 但无法保持 同一性
| 1 | // 内建对象的同一性 | 
- 类型转换
Kotlin 不会将较小的数据类型隐式地转换为较大的数据类型. 也就是说, 如果不进行显式类型转换, 我们就不能将一个 Byte 类型值赋给一个 Int 类型的变量。你需要使用 toInt() 显式扩大为更大的类型, Number 类中定义了向各个数据类型转换的方式。
| 1 | val bb : Byte = 1 | 
- 数值运算符
| 1 | shl(bits) – 带符号左移 (等于 Java 的<<) | 
字符类型
Char 类型不是 Number 的子类,也就是说 Char 类型并不是数值类型。 Char 类型使用 单引号 如 'a' 表示。特殊字符使用反斜线转义表达. Kotlin支持的转义字符包括: \t, \b, \n, \r, \', \", \\, \$ 。 其他任何字符, 都可以使用 Unicode 转义表达方式: '\uFF00'。
Char 类型也具有一系列的类型转换方法,你可以使用 '0'.toInt() 这样的语法将 Char 类型转换为数值类型。
可以使用 Char? 类型对 Char 类型进行装箱操作,与数值类型一样,装箱操作不能保持对象同一性。
布尔类型
Boolean 类型用来表示布尔值, 有两个可能的值: true 和 false.
当需要一个可为 null 的布尔值引用时, 布尔值也会被装箱(box).
布尔值的计算与 Java 相同。
数组类型
Kotlin 中的数组通过 Array 类表达, 这个类拥有 get 和 set 函数(这些函数通过运算符重载转换为 [] 运算符), 此外还有 size 属性, 以及其他一些有用的成员函数。
Kotlin 中也有专门的类来表达基本数据类型的数组: ByteArray, ShortArray, IntArray 等等, 这些数组可以避免数值对象装箱带来的性能损耗. 这些类与 Array 类之间不存在继承关系, 但它们的方法和属性是一致的. 各个基本数据类型的数组类都有对应的工厂函数。
| 1 | // 初始化一个 Array | 
字符串类型
使用双引号 "abc" 表示转移字符串,支持转义字符。使用三个双引号 """abc""" 表示原生字符串,原生字符串不支持转义,可以包含任何转义字符。
| 1 | // 默认使用 | 分割 | 
字符串模板,转义字符串和原生字符串都支持字符串模板,使用 ${表达式} 的方式可以在字符串中间插入数据。只有一个简单值时可以省略 {} ,同时也支持复杂表达式的计算。转义字符串中你可以使用 \$ 来写入 $ 字符,原生字符串中由于不支持转义字符,你可以使用 ${"$"} 的方式写入 $ 字符。
| 1 | val user = User() | 
控制流
控制流主要包括判断结构,分支结构,循环结构
if 判断结构
| 1 | var a = 0 | 
when 分支结构
Kotlin 使用 when 关键字实现分支结构。
当 when 作为表达式出现时,必须具有 else 分支,除非你的分支已经包含了所有的情况,这是因为作为表达式时他必须有一个返回值,而 else 分支将会在所有条件都不满足时执行。
when 作为表达式
| 1 | fun testFun3(param: Int): Int = when (param) { | 
在函数中使用 when
| 1 | // 作为函数时不需要必须有 else 分支 | 
for 循环结构
任何值, 只要能够产生一个迭代器( iterator), 就可以使用 for 循环进行遍历。
能够产生一个迭代器是指:
存在一个成员函数- 或扩展函数 iterator(), 它的返回类型应该 存在一个成员函数- 或扩展函数 next(), 并且 存在一个成员函数- 或扩展函数 hasNext(), 它的返回类型为 Boolean 类型。
遍历数组和 List 
| 1 | // 遍历临时数组 | 
遍历 map
| 1 | // 遍历map | 
遍历字符串
| 1 | // 遍历字符串 | 
while 循环结构
用法与其他语言是一致的。
| 1 | var a = 0 | 
返回与跳转
Kotlin 中有三种标签可以跳出程序流程
return. 默认行为是, 从最内层的函数或 匿名函数 中返回。
break. 结束最内层的循环。
continue. 在最内层的循环中, 跳转到下一次循环。
Kotlin 中的任何表达式都可以用 label 标签来标记。标签的形式与标识符相同, 后面附加一个 @ 符号,如 loopOut@,使用标签标记位置,就可以使用程序跳出操作符跳出指定位置,如 break@loopOut,continue@loopOut,return@loopOut。需要注意的是中间不需要有空格,他们是一体的。如果有标签的同时又有返回值,使用 return@loopOut 100 这样的形式,意为跳出到 loopOut 标签位置,返回值是 100 。
| 1 | fun testFun6() { | 
在
Kotlin中, 通过使用字面值函数(function literal), 局部函数(local function), 以及对象表达式(object expression), 允许实现函数的嵌套。通过标签限定的return语句, 可以从一个外层函数中返回. 最重要的使用场景是从Lambda表达式中返回。
如下面的例子中,默认会从函数 testFun61() 中返回,返回值为9,而且你写 return 语句时,编译器会提示你必须返回一个 Int 类型。这种非局部的返回(non-local return), 仅对传递给 内联函数(inline function) 的 Lambda 表达式有效。
| 1 | // 函数会返回 9 | 
如果需要从内部 Lambda 表达式跳出而不是从函数中返回,可以使用标签指定跳出目标。使用隐含标签会更方便一些, 隐含标签的名称与 Lambda 表达式被传递去的函数名称相同。如下面的隐含标签为 forEach@。
| 1 | // 此时返回 0 |