4.Kotlin_表达式&关键字
if
表达式
在Kotlin
中,if
是一个表达式,即它会返回一个值,每个条件分支都隐式地返回其最后一行的表达式的结果,因此无需使用return关键字。因此就不需要三元运算符条件 ? 然后 : 否则
,因为普通的if
就能胜任这个角色。
if
的分支可以是代码块,最后的表达式作为该块的值:
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
when
表达式
when
表达式与Java
中的switch/case
类似,但是要强大的多。这个表达式会去试图匹配所有可能的分支直到找到满意的一项。
然后它会运行右边的表达式。
与Java
的switch/case
不同之处是参数可以是任何类型,并且分支也可以是一个条件。
对于默认的选项,我们可以增加一个else
分支,它会在前面没有任何条件匹配时再执行。条件匹配成功后执行的代码也可以是代码块:
when (x){
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("I'm a block")
print("x is neither 1 nor 2")
}
}
因为它是一个表达式,它也可以返回一个值。我们需要考虑什么时候作为一个表达式使用,它必须要覆盖所有分支的可能性或者实现else
分支。否则它不会被编译成功:
val result = when (x) {
0, 1 -> "binary"
else -> "error"
}
如你所见,条件可以是一系列被逗号分割的值。但是它可以有更多的匹配方式。比如,我们可以检测参数类型并进行判断:
when(view) {
is TextView -> view.setText("I'm a TextView")
is EditText -> toast("EditText value: ${view.getText()}")
is ViewGroup -> toast("Number of children: ${view.getChildCount()} ")
else -> view.visibility = View.GONE
}
示例:when对if else的改造
fun schedule(day: Day, sunny: Boolean) = {
if (day == Day.SAT) {
basketball()
} else if (day == Day.SUN) {
fishing()
} else if (day == Day.FRI) {
appointment()
} else {
if (sunny) {
library()
} else {
study()
}
}
}
上面的例子中因为存在不少if else分支,代码显得不够优雅,更好的改进方法是用when表达式来优化:
fun schedule(sunny: Boolean, day: Day) = when (day) {
Day.SAT -> basketball()
Day.SUN -> fishing()
Day.FRI -> appointment()
else -> when {
// when关键字的参数可以省略
sunny -> library()
else -> study()
}
}
一个完整的when表达式类似switch语句,由when关键字开始,用花括号包含多个逻辑分支,每个分支由-> 连接, 不再需要switch的break(这真是一个恼人的关键字),由上往下匹配,一直匹配完为止,否则执行else分支的逻辑,类似switch的default。
到这里你可能会说上面的例子中,这样嵌套子when表达式,层次依旧比较深。要知道when表达式是很灵活的,我们很容易通过如下修改来解决这个问题:
fun schedule(sunny: Boolean, day: Day) = when {
day == Day.SAT -> basketball()
day == Day.SUN -> fishing()
day == Day.FRI -> appointment()
sunny -> library()
else -> study()
}
这样就会更优雅了。
for循环
val items = listOf("apple", "banana", "kiwi")
for (item in items) {
println(item)
}
for (i in array.indices)
print(array[i])
在Kotlin中用in关键字来检查一个元素是否是一个区间或集合中的成员。如果我们在in前面加上感叹号,那么就是相反的判断结果。
Ranges
Range
表达式使用一个..
操作符。表示就是一个该范围内的数据的数组,包含头和尾:
var nums = 1..100
for(num in nums) {
println(num)
// 打印出1 2 3 ....100
}
if(i >= 0 && i <= 10)
println(i)
转换成
if (i in 0..10)
println(i)
Ranges默认会自增长,所以如果像以下的代码:
for (i in 10..0)
println(i)
它就不会做任何事情。但是你可以使用downTo
函数:
for(i in 10 downTo 0)
println(i)
我们可以在Ranges
中使用step
来定义一个从1
到一个值的不同的空隙:
for (i in 1..4 step 2) println(i)
for (i in 4 downTo 1 step 2) println(i)
Until
上面的Range
是包含了头和尾,那如果只想包含头不包含尾呢? 就要用until
:
var nums = 1 until 100
for(num in nums) {
println(num)
// 这样打印出来是1 2 3 .....99
}
上面in、step、downTo、until这几个,他们可以不通过点号,而是通过中缀表达式来被调用,从而让语法变得更加简洁直观。
Kotlin
用到的关键字
var
:定义变量val
:定义常量fun
:定义函数Unit
:默认方法返回值,类似于Java
中的void
,可以理解成返回没什么用的值类型vararg
:可变参数$
:字符串模板(取值)- 位运算符:
or
(按位或),and
(按位与),shl
(有符号左移),shr
(有符号右移), ushr
(无符号右移),xor
(按位异或),inv
(按位取反)in
:在某个范围中 检查值是否在或不在(in/!in
)范围内或集合中downTo
:递减,循环时可用,每次减1step
:步长,循环时可用,设置每次循环的增加或减少的量when
:Kotlin
中增强版的switch
,可以匹配值,范围,类型与参数is
:判断类型用,类似于Java
中的instanceof()
,is
运算符检查表达式是否是类型的实例。 如果一个不可变的局部变量或属性是指定类型, 则不需要显式转换private
仅在同一个文件中可见protected
同一个文件中或子类可见public
所有调用的地方都可见internal
同一个模块中可见abstract
抽象类标示final
标识类不可继承,默认属性enum
标识类为枚举open
类可继承,类默认是final
的annotation
注解类init
主构造函数不能包含任何的代码。初始化的代码可以放到以init
关键字作为前缀的初始化块(initializer blocks
)中field
只能用在属性的访问器内。特别注意的是,get set
方法中只能使用filed
。属性访问器就是get set
方法。:
用于类的继承,变量的定义..
范围操作符(递增的)1..5
,2..6
千万不要6..2
::
作用域限定符inner
类可以标记为inner {: .keyword }
以便能够访问外部类的成员。内部类会带有一个对外部类的对象的引用object
对象声明并且它总是在object{: .keyword }
关键字后跟一个名称。对象表达式:在要创建一个继承自某个(或某些)类型的匿名类的对象会用到
- 邮箱 :[email protected]
- Good Luck!