第二章 基础语法
-
在Kotlin中,如果函数没有返回值,函数会默认被当成 Unit 类型。而 Java 中是void 关键字来标识的。
它们的区别是什么? Unit 是一个类型,而void 是一个关键字。 -
val : 引用不可变, 使用 val声明的变量具有Java 中的final关键字效果。这里强调的是引用不可变。
-
优先使用val 来避免副作用:尽可能采用val、不可变对象及纯函数老设计程序。
-
Kotlin 天然支持了部分函数式特性。函数式语言一个典型的特征就在于 函数是头等公民。
-
高阶函数(更加抽象):接受一个或多个过程(函数)为参数;或者以一个过程(函数)作为返回结果。
-
函数类型的格式:(Int) -> Unit。
- 使用 -> 符号来组织参数类型和返回值类型,左边是参数类型,右边是返回值类型;
- 必须使用一个括号来包裹参数类型。
- 返回值类型即使是Unit,也必须显式声明。(如果没有参数使用直接使用“()”)
Kotlin 支持为声明参数指定名字:(errCode:Int,errMsg:String)-> Unit.
如果要表示该函数类型可选 : ((errCode:Int,errMsg:String)-> Unit)?。
高阶函数还支持返回一个函数 :(Int)->((Int)->Unit);
-
Kotlin 中通过两个冒号来实现对于某个类的方法进行引用。
-
Lambda 表达式 是一种语法糖,简化表达后的匿名函数。
- 一个Lambda 表达式必须通过{}来包裹
- 如果Lambda声明了参数部分的类型,且返回值类型支持类型推导。那么Lambda变量就可以省略函数类型声明。
- 如果Lambda 变量声明了函数类型,那么Lambda的参数部分的类型就可以省略。
如果 Lambda表达式返回的不是Unit,那么默认最后一行表达式的值类型就是返回值类型。
-
柯里化(Currying):指的是把接收多个参数的函数变成一系列仅接收单一参数函数的过程。
- fun sum(x:Int,y:Int,z:Int) = x+y+z
(柯里化)fun sum(x:Int) = {y:Int -> {z:Int -> x+y+z}}
调用方式:println(sum(1,2,3))
(柯里化)println(sum(1)(2)(3))
- fun sum(x:Int,y:Int,z:Int) = x+y+z
-
Koltin中的扩展函数允许我们在不修改已有类的前提下,给它增加新的方法。
为View添加一个隐藏方法。fun View.invisible(){ this.visibility = View.INVISIBLE }
-
面向表达式编程:表达式和语句是不同的概念。
- 表达式可以是一个值、常量、变量、操作符、函数、或者它们之间的组合,编程语言对其进行解释和计算,以求产生另一个值。
- Unit类型:让函数调用皆为表达式。Unit作为一种类型引入,代替了Java的void关键字,结果是Kotlin函数在所有情况下都具有返回值类型。(也就满足了表达式的意思)
- Unit是一种类型,但是它不代表任何信息,他的实例只有一个,可写为();
-
Kotlin中的 “?:”:这里的问号和冒号必须放在一起使用,它被称为Elvis运算符,或者null 合并运算符。Kotlin中可以用"?“来表示一种类型的可空性,我们可以用”?:"来给一种可空类型的变量指定为空的情况下的值。
-
When表达式:
- 每个逻辑分支具有返回值,最终整个when表达式的返回值就是所有分支相同的返回类型,或者公共的父类型。
- when关键字的参数可以省略,但是这种情况下,分支 -> 的左侧部分需要返回布尔值类型。
-
for 循环
- 范围表达式:1…10 [1,10];step函数来定义迭代的步长
for(i in 1..10 step 2) print("$i ") >>>1 3 5 7 9
- 倒序使用 downTo方法来实现
for(i in 10 downTo 1 step 2) print("$i ") >>> 10 8 6 4 2
- 使用 until 函数 实现 一个半开区间:1 until 10 ===[1,10)
for(i in 1 until 10) print("$i ") >>>1 2 3 4 5 6 7 8 9
- 使用 in 关键字,在kotlin中用它来对检查一个元素是否在一个区间或者集合中的成员。在其前面加上"!"来去相反。
"a" in listOf("b","c") >>> res4: kotlin.Boolean = false "a" !in listOf("b","c") >>> res5: kotlin.Boolean = true
- 任何提供了迭代器(iterator)的结构都可以用for语句进行迭代;还可以通过withIndex方法,提供一个键值元组。
val array = listOf("a","b","c","d") for (c in array) print("$c ") println("------------------") for((index,value) in array.withIndex()){ println("index $index --> value $value ;") } >>>> a b c d ------------------ >>> index 0 --> value a ;index 1 --> value b ;index 2 --> value c ;index 3 --> value d ;
-
中缀表达式:A 中缀方法 B。
- 需要用 infix 关键字修饰 才表示是中缀表达式。
定义满足中缀表达式的条件 - 该中缀函数必须是某个类型的扩展函数或者成员方法,
- 该中缀函数只能有一个参数;
- 虽然Kotlin中的函数参数支持默认值,但中缀表达式的参数不能有默认值
- 该参数不能是可变参数。
to 就是一个中缀表达式。
val map = mapOf( 1 to "one", 2 to "two", 3 to "three" ) for(m in map){ println("${m.key}--->${m.value}") } >>> 1--->one >>> 2--->two >>> 3--->three
- 尝试定义一个中缀表达式
class Person{ infix fun called(name: String){ println("My name is $name") } } fun main() { val p = Person() p called "小明" } >>> My name is 小明
- 需要用 infix 关键字修饰 才表示是中缀表达式。
-
字符串定义和操作
- 定义原生字符串(不需要使用麻烦的转义字符):使用三个引号 来声明,效果是:输入的是什么就是什么。
val str = """ \n \n / \\\\ ... """ println(str)
- 字符串判等
Koltin中判断性主要两种类型:- 结构相等:通过操作符 == 来判断两个对象的内容是否相等。
- 引用相等:通过操作符 === 来判断两个对象的引用是否一致,与之相反的判断符是 !== 。