《kotlin实战》学习总结(1)kotlin基础
kotlin实战(1)kotlin基础
关于《kotlin实战》的学习总结
1函数和变量
fun main(args: Array<String> {
println("Hello, world!")
}
由上面这些代码我们可以观察到:
- 关键字 fun ,用来声明一个函数;
- 参数类型写在参数的名称后面,与变量相同;
- 函数可以定义在文件的最外层,不需要放入类中。(当这种函数与定义在类中的函数重名且在类中调用时,默认调用的是类中的函数);
- 数组就是类,没有特殊语法;
- kotlin将System.out.println封装成了println;
- 省略了句尾的分号;
1.1函数
函数的返回类型放在参数列表之后
fun max(a: Int, b: Int): Int{
return if(a > b) a else b
}
1.1.1语句与表达式
kotlin中,if是表达式,而不是语句。
区别在于,表达式有值并能作为另一个表达式的一部分使用,
而语句在代码块之中,没有自己的值
1.1.2表达式函数体
当函数的函数体是由单个表达式构成,可以用这个表达式作为完整的函数体,并去掉花括号和return语句:
fun max(a: Int, b: Int): Int = if(a > b) a else b
表达式函数体的返回类型可以省略,即类型推导:
fun max(a: Int, b: Int) = if(a > b) a else b
1.2变量
声明变量时,如果不指定变量类型,编译器进行类型推导。
1.2.1可变变量和不可变变量
var number = 3
var number: Int = 3
val str = "string"
val str: String = "string"
声明变量的关键字有两个:
- val (即value) ——不可变引用,对应java的final。
- var (即variable)——可变引用,对应普通的java变量
默认情况下应尽量使用val关键字来声明变量,仅在必要的时候换成var。使用不可变引用、不可变对象及无副作用的函数会让你的代码更加接近函数式编程风格。
2类和属性
kotlin省略了java中构造方法中重复的代码,且kotlin中public是默认的可见性。
2.1属性
class Person(val name: String, var sex: String)
kotlin中,属性是头等的语言特性,当你声明属性的时候,你就声明了对于的访问器(val属性只有getter,而var属性既有getter也有setter)。
val person = Person("Bob", "male")
printlin(person.name)
>>> Bob
kotlin中可以直接访问属性,但调用的依然是getter或setter。
2.1.1自定义访问器
实现一个自定义的访问器:
class Rectangle(val height: Int, val width: Int) {
val isSquare: Boolean
get(){
return height == width
}
}
3表示和处理选择:枚举和:“when”
when结构是java中switch结构的替代品,但when更加强大。
3.1声明枚举类
enum class Color{
RED, ORANGE, YELLOW, GREEN, INDIGO, VIOLET
}
kotlin中enum是个软关键字,它只在class前面的时候才有特殊的意义
3.1.1声明一个带属性的枚举类
enum class Color(val r : Int, val g: Int, val b : Int){
RED(255, 0, 0), ORANGE(255, 165, 0), YELLOW(255, 255, 0);
fun rbg() = (r * 255 + g) * 256 + b
}
当要在枚举类中定义方法时,就要使用分号将枚举常量列表和方法定义分开,这是kotlin唯一要使用分号的地方。
3.1.2用“when”处理枚举类
和if相似,when是一个有返回值的表达式,因此可以写一个直接返回when表达式的表达式体函数。
fun getMneminic(color: Color) =
when (color) {
Color.RED -> "Richard"
Color.ORANGE -> "Of"
}
]
与java不同,不需要在每个分支后面写break语句。kotlin中如果匹配成功,只有对应的分支会执行。也可以把多个值合并到同一个分支,只需要用逗号隔开这些值。
fun getWarmth(color: Color) =
when (color) {
Color.RED,Color.ORANGE,Color.YELLOW -> "WARN"
Color.GREEN -> "NEUTRAL"
}
导入枚举常量后不用限定词就可以访问
import ch01.colors.Color
import ch01.colors.Color.*
fun getWarmth(color: Color) =
when (color) {
RED,ORANGE,YELLOW -> "WARN"
GREEN -> "NEUTRAL"
}
3.1.3在when结构中使用任意对象
switch要求必须使用常量作为分支条件,when允许使用任何对象。
3.1.4使用不带参数的when
如果没有给when表达式提供参数,分支条件就是任意的布尔表达式。
4迭代:“while”循环和“for”循环
4.1“while”循环
kotlin中while循环和do- while循环与java中没有任何区别。
4.2迭代数字:区间和数列
为了代替java中的先初始化变量,然后更新变量值并在满足某个限制条件时退出的循环用法,kotlin使用了区间的概念。
区间本质上是两个值之间的间隔,这两个值通常是数字:一个是起始值,一个是结束值。使用…运算符来表示区间:
val oneToTen = 1…10
区间始终是包含或者是闭合的,意味着第二个值(上面的10)始终是区间的一部分。
如果能迭代区间中所有的值,这样的区间被称作数列。
4.2.1 步长
for(i in 100 downTo 1 step 2){
print(i)
}
>>> 100 98 96 94 92......
downTo 表示降序, step 表示步长。
until 与 …等效。
4.2.2 迭代map
val binaryReps = TreeMap<Char, String>()
for(c in 'a'..'f') {
val binary = Integer.toBinaryString(c.toInt())
binaryReps[c[ = binary
}
for((letter, binary) in binaryReps) {
println("$letter = $binary")
}
…语法不仅可以创建数字区间,还可以创建字符区间。
kotlin中可以通过map[key] 来读取值,可以通过map[key] = value来设置值,而不需要调用get和put方法。
当需要跟踪集合中当前项的下标时我们可以使用与((letter, binary) in binaryReps)同样的展开语法:
val list = arrayListOf("10", "11", "12")
for((index, element) in list.withIndex()) {
print($index : $element)
}
4.2.3 使用“in”检查集合和区间成员
使用in运算符来检查一个值是否在区间中,或者它的逆运算,!in,来检查这个值是否不在这个区间中。
fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'
fun isNotDigit(c: Char) = c !in '0'..'9'
print(isLetter('q'))
>>>true
print(isNotDigit('x'))
>>> false
c in ‘a’…‘z’ 其实等效于 a <= c && c <= z。当某个类支持实例的比较操作时,也能创建这种类型的对象的区间。
print("kotlin" in "java".."scala")
>>> true
等效于 “java” <= “kotlin” && “kotlin” <= “scala” (String的比较器是按照字母表进行比较的)
in检查同样适用于集合:
print("kotlin" in setOf("java", "scala"))
>>>faslse
由于kotlin不在集合中,所以结果为false。
5 kotlin中的异常
kotlin中的异常处理与java中相似。但kotlin不需要new关键字来创建异常实例(与其他所有类一样)而且kotlin中throw结构是一个表达式,能作为另一个表达式的一部分使用。除此之外,和java最大的区别就在于kotlin不要求你声明函数可以抛出的异常。
5.1 “try”作为表达式
kotlin中的try关键字跟if和when一样,引入了一个表达式,可以把它的值赋给一个变量。如果一个try代码执行正常那么,代码块中最后一个表达式就是结果,如果出现异常,则catch中最后一个表达式就是结果。