1.内置数字类型:
2.float:单精度 double:双精度
3.Kotlin 中的数字没有隐式拓宽转换。 例如,具有 Double 参数的函数只能对 Double 值调用,而不能对 Float 、 Int 或者其他数字值调用。
4.Kotlin不支持八进制
6. ==:结构相等 ===:引用相等
7.位运算(只用于 Int 与 Long ):
shl(bits) – 有符号左移
shr(bits) – 有符号右移
ushr(bits) – 无符号右移
and(bits) – 位与
or(bits) – 位或
xor(bits) – 位异或
8.Kotlin 为无符号整数引入了以下类型:
kotlin.UByte : 无符号 8 比特整数,范围是 0 到 255
kotlin.UShort : 无符号 16 比特整数,范围是 0 到 65535
kotlin.UInt : 无符号 32 比特整数,范围是 0 到 2^32 - 1
kotlin.ULong : 无符号 64 比特整数,范围是 0 到 2^64 - 1
9.Kotlin 提供了用后缀标记整型字面值来表示指定无符号类型,后缀 u 与 U 将字面值标记为无符号.确切类型会根据预期类型确定。如果没有提供预期的类型,会根据字面值大小选择 UInt 或者 ULong
10.只要表达式中的第一个元素是字符串,就可以用 + 操作符连接字符串。如 : val s = "abc" + 1,但在大多数情况下,优先使用字符串模板或原始字符串而不是字符串连接。
11.Kotlin 有两种类型的字符串字面值,转义字符串 : val s = "Hello, world!\n" 和原始字符串val text = """
for (c in "foo")
print(c)
"""
12.字符串模板:模板表达式以美元符( $ )开头,由一个简单的名字构成 : println("i = $i") 或者用花括号括起来的任意表达式 : println("$s.length is ${s.length}")
13.导入的包的名字如果与本地的包冲突,可以使用 as 关键字在本地重命名冲突项来消歧义:
import org.example.Message // Message 可访问
import org.test.Message as testMessage // testMessage 代表“org.test.Message”
14.可见性:
包:如果你不指定任何可见性修饰符,默认为 public ,这意味着你的声明将随处可见;
如果你声明为 private ,它只会在声明它的文件内可见;
如果你声明为 internal ,它会在相同模块内随处可见;
protected 不适用于顶层声明。
类:
private 意味着只在这个类内部(包含其所有成员)可见;
protected —— 和 private 一样 + 在子类中可见。
internal —— 能见到类声明的 本模块内 的任何客户端都可见其 internal 成员;
public —— 能见到类声明的任何客户端都可见其 public 成员。
构造函数:
要指定一个类的的主构造函数的可见性,使用以下语法(注意你需要添加一个显式
constructor 关键字):
class C private constructor(a: Int) { …… }
局部声明:
局部变量、函数和类不能有可见性修饰符。
15.if 的分支可以是代码块,最后的表达式作为该块的值:
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
16.Kotlin的when取代了c的switch:
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x is neither 1 nor 2")
}
}
如果 when 作为一个表达式使用,则必须有 else 分支, 除非编译器能够检测出所有的可能情况都已经覆盖了
16.要为一个表达式加标签,我们只要在其前加标签即可。我们可以用标签限制 break 或者 continue:
loop@ for (i in 1..100) {
for (j in 1..100) {
if (……) break@loop
}
}
标签限制的 break 跳转到刚好位于该标签指定的循环后面的执行点。 continue 继续标签指定的循环的下一次迭代。
17.类声明由类名、类头(指定其类型参数、主构造函数等)以及由花括号包围的类体构成。类头与类体都是可选的; 如果一个类没有类体,可以省略花括号。
18.在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数 : class Person constructor(firstName: String) { /*……*/ },如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字 : class Person(firstName: String) { /*……*/ }主次构造函数
19.如果一个非抽象类没有声明任何(主或次)构造函数,它会有一个生成的不带参数的主构造函数。构造函数的可见性是 public。如果你不希望你的类有一个公有构造函数,你需要声明一个带有非默认可见性的空的主构造函数:class DontCreateMe private constructor () { /*……*/ }
20.要让类可以被继承,要先声明open : open class Base
21.可以用一个 var 属性覆盖一个 val 属性,但反之则不行。 这是允许的,因为一个val 属性本质上声明了一个 get 方法, 而将其覆盖为 var 只是在子类中额外声明一个set 方法。
22.在构造派生类的新实例的过程中,第一步完成其基类的初始化(在之前只有对基类构造函数参数的求值),因此发生在派生类的初始化逻辑运行之前。(基类是父类)
23.在 Kotlin 中,实现继承由下述规则规定:如果一个类从它的直接超类继承相同成员的多个实现, 它必须覆盖这个成员并提供其自己的实现(也许用继承来的其中之一)。 为了表示采用从哪个超类型继承的实现,我们使用由尖括号中超类型名限定的 super ,如 super<Base>.成员
24.类以及其中的某些成员可以声明为 abstract ,即抽象类。 抽象成员在本类中可以不用实现,且抽象类不需要用open标注.
25.一个只读属性的语法和一个可变的属性的语法有两方面的不同:1、只读属性的用 val 开始代替 var 2、只读属性不允许 setter
26.自定义getter和setter:
27.以const修饰符标识编译期常量的条件:
位于顶层或者是 object 声明 或 companion object 的一个成员
以 String 或原生类型值初始化
没有自定义 getter
28.一个非空且非原生类型想过一会再初始化,可以通过lateinit 修饰符标记该属性
29.在实现多个接口时,如果遇到一个方法在多个接口都有实现时,可通过如下进行声明:
class D : A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
}
override fun bar() {
super<B>.bar()
}
30.可以为一个你不能修改的、来自第三方库中的类编写一个新的函数。 这个新增的函数就像那个原始类本来就有的函数一样,可以用普通的方法调用。 这种机制称为 扩展函数 。此外,也有 扩展属性 , 允许你为一个已经存在的类添加新的属性。
为MutableList<Int>添加swap函数:
fun MutableList<Int>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // “this”对应该列表
this[index1] = this[index2]
this[index2] = tmp
}
可以通过泛化使这个函数对任何 MutableList起作用:
fun<T>MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // “this”对应该列表
this[index1] = this[index2]
this[index2] = tmp
}