kotlin学习一:基础语法

目录
  • kotlin学习一:基础
    • 基本类型
    • 类型转换
    • 位运算
    • 布尔运算true 与 false。
    • 变量赋值
      • val
      • var
      • 空值与null:
      • 字符串使用
    • 控制流逻辑
      • if条件表达式
      • while循环
      • when表达式
      • for循环
        • in的使用技巧
          • 2 区间迭代
          • 3 数列迭代
      • 返回和跳转

kotlin学习一:基础

基本类型

整数四种类型:
浮点数类型:默认 double:123.5、123.5e10,Float 用 f 或者 F 标记: 123.5f

类型 大小(比特数) 有效数字比特数 指数比特数 十进制位数
Float 32 24 8 6-7
Double 64 53 11 15-16
Byte 8 -128-127
Short 16 -32768-32767
Int 32 -2,147,483,648 (-231)
Long 64 -9,223,372,036,854,775,808 (-263)

大数可以采用面值下划线:增强可读性

val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

类型转换

因此较小的类型不能隐式转换为较大的类型

可以显式转换来拓宽数字

val i: Int = b.toInt() // OK:显式拓宽
print(i)

算数运算会有重载,会适当的转换;

val l = 1L + 3 // Long + Int => Long

位运算

val x = (1 shl 2) and 0x000FF000

这是完整的位运算列表(只用于 IntLong):

  • shl(bits) – 有符号左移
  • shr(bits) – 有符号右移
  • ushr(bits) – 无符号右移
  • and(bits) – 位
  • or(bits) – 位
  • xor(bits) – 位异或
  • inv() – 位非

布尔运算true 与 false。

  • || – 短路逻辑或
  • && – 短路逻辑与
  • ! - 逻辑非

变量赋值

val

只能复制一次:写法:

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


var

可重新赋值的变量,

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

举例:

val PI = 3.14
var x = 0

fun incrementX() { 
    x += 1 
}

空值与null:

可以为null时,需要在类型后面加?

当某个变量的值可以为 null 的时候,必须在声明处的类型后添加 ? 来标识该引用可为空。

如果 str 的内容不是数字返回 null。

//类型后面加?表示可为空
var age: String? = "23" 
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1

当一个引用可能为 null 值时, 对应的类型声明必须明确地标记为可为 null。

当 str 中的字符串内容不是一个整数时, 返回 null:

fun parseInt(str: String): Int? {
  // ...
}

以下实例演示如何使用一个返回值可为 null 的函数:

fun main(args: Array) {
  if (args.size < 2) {
    print("Two integers expected")
    return
  }
  val x = parseInt(args[0])
  val y = parseInt(args[1])
  // 直接使用 `x * y` 会导致错误, 因为它们可能为 null.
  if (x != null && y != null) {
    // 在进行过 null 值检查之后, x 和 y 的类型会被自动转换为非 null 变量
    print(x * y)
  }
}

字符串使用

$,来提取变量为字符串,或者${ },来使用字符串。

var a = 1
// 模板中的简单名称:
val s1 = "a is $a" 

a = 2
// 模板中的任意表达式:
val s2 = "${s1.replace("is", "was")}, but now is $a"

// 结果
a was 1, but now is 2

控制流逻辑

if条件表达式

fun maxOf(a: Int, b: Int) = if (a > b) a else b

while循环

val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
    println("item at $index is ${items[index]}")
    index++
}
//do while循环
while (x > 0) {
    x--
}

do {
  val y = retrieveData()
} while (y != null) // y 在此处可见

when表达式

fun describe(obj: Any): String =
    when (obj) {
        1          -> "One"
        "Hello"    -> "Greeting"
        is Long    -> "Long"
        !is String -> "Not a string"
        else       -> "Unknown"
    }


for循环

变量in集合

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

in的使用技巧

1 当作条件语句:x in 1..y+1 ,

val x = 10
val y = 9
//使用 *in* 运算符来检测某个数字是否在指定区间内:
if (x in 1..y+1) {
    println("fits in range")
//检测某个数字是否在指定区间外:
if (list.size !in list.indices) {
    println("list size is out of valid list indices range, too") 
}
2 区间迭代
for (x in 1..5) {
    print(x)
}
3 数列迭代
for (x in 1..10 step 2) {
    print(x)
}
println()
for (x in 9 downTo 0 step 3) {
    print(x)
}

返回和跳转

https://www.kotlincn.net/docs/reference/returns.html

  • return。默认从最直接包围它的函数或者匿名函数返回。
  • break。终止最直接包围它的循环。
  • continue。继续下一次最直接包围它的循环。

任何表达式都可以用@来标记,为一个表达式加标签,只需要在其前加标签。限制break等的作用范围。

loop@ for (i in 1..100) {
    for (j in 1..100) {
        if (……) break@loop
    }
}

return返回标签:

Kotlin 有函数字面量、局部函数和对象表达式。因此 Kotlin 的函数可以被嵌套。

防止表达式具体值的返回, 可以用标签限制返回值

Kotlin 有函数字面量、局部函数和对象表达式。因此 Kotlin 的函数可以被嵌套。 标签限制的 return 允许我们从外层函数返回。 最重要的一个用途就是从 lambda 表达式中返回。回想一下我们这么写的时候:

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return // 非局部直接返回到 foo() 的调用者
        print(it)
    }
    println("this point is unreachable")
}

Target platform: JVMRunning on kotlin v. 1.3.72

这个 return 表达式从最直接包围它的函数即 foo 中返回。 (注意,这种非局部的返回只支持传给内联函数的 lambda 表达式。) 如果我们需要从 lambda 表达式中返回,我们必须给它加标签并用以限制 return

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // 局部返回到该 lambda 表达式的调用者,即 forEach 循环
        print(it)
    }
    print(" done with explicit label")
}

Target platform: JVMRunning on kotlin v. 1.3.72

现在,它只会从 lambda 表达式中返回。通常情况下使用隐式标签更方便。 该标签与接受该 lambda 的函数同名。

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调用者,即 forEach 循环
        print(it)
    }
    print(" done with implicit label")
}

Target platform: JVMRunning on kotlin v. 1.3.72

或者,我们用一个匿名函数替代 lambda 表达式。 匿名函数内部的 return 语句将从该匿名函数自身返回

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
        if (value == 3) return  // 局部返回到匿名函数的调用者,即 forEach 循环
        print(value)
    })
    print(" done with anonymous function")
}

Target platform: JVMRunning on kotlin v. 1.3.72

请注意,前文三个示例中使用的局部返回类似于在常规循环中使用 continue。并没有 break 的直接等价形式,不过可以通过增加另一层嵌套 lambda 表达式并从其中非局部返回来模拟:

fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // 从传入 run 的 lambda 表达式非局部返回
            print(it)
        }
    }
    print(" done with nested loop")
}

Target platform: JVMRunning on kotlin v. 1.3.72

当要返一个回值的时候,解析器优先选用标签限制的 return,即

return@a 1

意为“返回 1@a”,而不是“返回一个标签标注的表达式 (@a 1)”。

参考链接:

https://www.kotlincn.net/docs/reference/returns.html

你可能感兴趣的:(kotlin学习一:基础语法)