Kotlin第一天:基本语法


本着上去就是干的原则,学习kotlin第一天,看了一些基本语法;有点java基础知识的应该没有太多问题

定义函数

fun sum(a: Int, b: Int): Int {
    return a + b
}

定义一个含有两个Int入参,返回值为Int的函数
和java不同点:
1、形参类型写在参数名后面,基本类型都是对象,必须大写
2、返会类型写在函数末尾
3、fun 关键字开头
4、将表达式作为函数体、返回值类型自动推断的函数:

fun sum(a: Int, b: Int) = a + b

5、函数返回无意义的值:

fun printSum(a: Int, b: Int): Unit {
    println("sum of $a and $b is ${a + b}")
}

Unit相当于java中Void
无意义返回值可以省略

fun printSum(a: Int, b: Int) {
    println("sum of $a and $b is ${a + b}")
}

定义变量

定义的变量前都需要加val或var,val定义只读变量,var定义可读可写的变量

val a: Int = 1  // 立即赋值
val b = 2   // 自动推断出 `Int` 类型
val c: Int  // 如果没有初始值类型不能省略
c = 3       // 明确赋值

var 变量可以重新赋值

var x = 5 // 自动推断出 `Int` 类型
x += 1

字符串模板

相比java的字符串模板,kotlin强大了很多,不需要区分整形字符串等类型,字符串可以包含模板表达式 ,即一些小段代码,会求值并把结果合并到字符串中。 模板表达式以美元符($)开头,由一个简单的名字构成:
简单的值替换

val i = 10
println("i = $i") // 输出“i = 10”

包含表达式

val s = "abc"
println("$s.length is ${s.length}") // 输出“abc.length is 3”

对于要加入$符号,不支持反斜杠

val price = """
${'$'}9.99
"""

空安全

空安全编译检测

在 Kotlin 中,类型系统区分一个引用可以容纳 null (可空引用)还是不能容纳(非空引用)。

var a: String = "abc"//a 非空引用
a = null // 编译错误
var b: String? = "abc"//可空引用
b = null // ok
print(b)

如果使用a和b变量

val l = a.length//ok
val l = b.length // 错误:变量“b”可能为空

如果我们要是使用可空引用,我们该如何做呢?

条件中检测null

显示的检测b是不是null

val l = if (b != null) b.length else -1

允许在if内调用b,但是前提是这只适用于 b 是不可变的情况(即在检查和使用之间没有修改过的局部变量 ,或者不可覆盖并且有幕后字段的 val 成员),因为否则可能会发生在检查之后 b 又变为 null 的情况。

if (b != null && b.length > 0) {
    print("String of length ${b.length}")
} else {
    print("Empty string")
}

安全调用

你的第二个选择是安全调用操作符,写作 ?.

val a = "Kotlin"
val b: String? = null
println(b?.length)
println(a?.length) // 无需安全调用

个人觉得最大的好处是可以链式调用

bob?.department?.head?.name

如果要只对非空值执行某个操作,安全调用操作符可以与 let 一起使用:

val listWithNulls: List<String?> = listOf("Kotlin", null)
for (item in listWithNulls) {
    item?.let { println(it) } // 输出 A 并忽略 null
}

还可以出现在左侧,只要任意一个环节为null,直接会跳过赋值,右侧表达式不会求值

// 如果 `person` 或者 `person.department` 其中之一为空,都不会调用该函数:
person?.department?.head = managersPool.getManager()

Elvis 操作符

elvis操作符 ?:
含义:当我们有一个可空的引用 r 时,我们可以说“如果 r 非空,我使用它;否则使用某个非空的值 x”:

val l: Int = if (b != null) b.length else -1
//等价于
val l = b?.length ?: -1

如果 ?: 左侧表达式非空,elvis 操作符就返回其左侧表达式,否则返回右侧表达式。 请注意,当且仅当左侧为空时,才会对右侧表达式求值。

请注意,因为 throw 和 return 在 Kotlin 中都是表达式,所以它们也可以用在 elvis 操作符右侧。这可能会非常方便,例如,检查函数参数:

fun foo(node: Node): String? {
    val parent = node.getParent() ?: return null
    val name = node.getName() ?: throw IllegalArgumentException("name expected")
    // ……
}

!! 操作符

!!操作符相当于一个非空检测屏蔽符,对于任何对象,使用!!后都会认为是非空的,如果是空的就出现NPE 异常

val l = b!!.length

类型安全转换

如果对象不是目标类型,那么常规类型转换可能会导致 ClassCastException。 另一个选择是使用安全的类型转换,如果尝试转换不成功则返回 null:
类型安全转换 as?

val aInt: Int? = a as? Int

可空类型的集合

如果你有一个可空类型元素的集合,并且想要过滤非空元素,你可以使用 filterNotNull 来实现:

val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList: List<Int> = nullableList.filterNotNull()
println(intList)//[1, 2, 4]

使用类型检测及自动类型转换

is 运算符检测一个表达式是否某类型的一个实例;后面不需要显示的转换就可以当成该类型使用

fun getStringLength(obj: Any): Int? {
    if (obj is String) {
        // `obj` 在该条件分支内自动转换成 `String`
        return obj.length
    }

    // 在离开类型检测分支后,`obj` 仍然是 `Any` 类型
    return null
}

//甚至
fun getStringLength(obj: Any): Int? {
    // `obj` 在 `&&` 右边自动转换成 `String` 类型
    if (obj is String && obj.length > 0) {
      return obj.length
    }

    return null
}

循环迭代

使用for

for 循环可以对任何提供迭代器(iterator)的对象进行遍历
获取值:

val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
    println(item)
}

获取索引

val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
    println("item at $index is ${items[index]}")
}

索引和值一起

for ((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}

while

do while 和while和java一样;

break和continue

break 和continue使用也和java一样

条件语句

if表达式

与java 的if不一样的地方是kotlin的if可以是语句,也可以是表达式;因此kotlin不需要java中的三元运算符"条件 ? 然后 : 否则"

// 传统用法
var max = a 
if (a < b) max = b

// With else 
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}
 
// 作为表达式
val max = if (a > b) a else b

if的分支可以是代码块,最后的表达式作为该块的值:

val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}

when语句(相当于switch)

when语句相当于switch语句,简单用法

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> { // 注意这个块
        print("x is neither 1 nor 2")
    }
}
和if语句一样,可以是表达式,也可以是语句,但作为表达式时,符合条件的分支的值就是整个表达式的值,每个分支它的值是块中最后的表达式的值
如果其他分支都不满足条件将会求值 else 分支

注意: 如果 when 作为一个表达式使用,则必须有 else 分支, 除非编译器能够检测出所有的可能情况都已经覆盖了[例如,对于 枚举(enum)类条目与密封(sealed)类子类型]。
如果很多分支需要用相同的方式处理,则可以把多个分支条件放在一起,用逗号分隔

when (x) {
    0, 1 -> print("x == 0 or x == 1")
    else -> print("otherwise")
}
我们可以用任意表达式(而不只是常量)作为分支条件
when (x) {
    parseInt(s) -> print("s encodes x")
    else -> print("s does not encode x")
}

我们也可以检测一个值在(in)或者不在(!in)一个区间或者集合中:

when (x) {
        in 1..10 -> {
            println("x is in the range 1")
            println("x is in the range 2")
        }
        in 200..300 -> print("x is valid")
        !in 10..20 -> print("x is outside the range")
        else -> print("none of the above")
    }
另一种可能性是检测一个值是(is)或者不是(!is)一个特定类型的值。注意: 由于智能转换,你可以访问该类型的方法与属性而无需任何额外的检测。
fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")
    else -> false
}

kotlin 1.3之后,还可以这样

fun Request.getBody() =
        when (val response = executeRequest()) {
            is Success -> response.body
            is HttpError -> throw HttpException(response.status)
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值