参考链接

Kotlin官方文档

https://kotlinlang.org/docs/home.html

本系列为参考Kotlin中文文档

https://download.csdn.net/download/u011109881/21418027

整理的笔记 不记得原pdf下载地址了

第一章 开始

知识点

1.kotlin主函数入口 kotlin方法

2.变量 注释 string 模板 条件表达式 空值检测 类型检测与自动类型转换 使用For循环  使用while循环 使用when表达式 使用区间 集合 创建类

笔记

package com.example.lib.d01start// 0 写在前面的话
// 将Kotlin转为Java步骤:
// Tools → Kotlin icon Kotlin → Show Kotlin Bytecode
// Decompile
// 会将Kotlin Code的二进制转为Java Code 方便对比学习// 同时可以在Android studio中将java code转换为kotlin code
// 选择Java file 右键 convert java file to kotlin file
// 一时不知道kotlin的语法 可以先写java 再转为kotlin
// 甚至可以先写好Java 的代码 直接copy到Kotlin文件中
// Android Studio 会检测到剪切板是Java Code 询问你是否将Java代码转换为Kotlin代码
// 点击确认 可以直接转换// 1 kotlin程序的入口
// 与普通的Java文件不同 写在类外部
fun main() {println("Hello World")// 2 Kotlin函数的学习method();
}fun method() {println(sum(13, 14));println(sum1(14, 14));println(printSum(13,15))println(printSum1(33,22))
}// kotlin方法的定义
/*方法关键字 方法名(参数1:参数1类型,参数2:参数2类型...):返回值类型{方法体}
*/
fun sum(a: Int, b: Int): Int {println("start $a+$b")return a + b
}// 如果方法体内部只有一句话 可以简写成如下
// 返回类型可以推断 “=”类似"return"
fun sum1(a: Int, b: Int) = a + b// 像sum方法内部有两行代码 无法缩写成sum1的样子
//fun sum2(a: Int, b: Int) = println("start $a+$b") a + b// 报错// Unit 无意义的值 类似于 void
fun printSum(a: Int, b: Int): Unit {println("sum of $a and $b is ${a + b}")
}// Unit类型可以忽略不写
// 方法体内部的$a $b代表变量的实际值
// ${a + b} {}内部是一个表达式
// 如果返回值类型是Unit 还会打印kotlin.Unit的信息
fun printSum1(a: Int, b: Int) {println("sum1 of $a and $b is ${a + b}")
}class D01Start {}
package com.example.lib.d01startimport java.lang.NumberFormatException
import java.util.*fun main() {// 3 变量variable()// 4 注释 略// 5 string 模板stringTemplate()// 6 条件表达式condition()// 7 空值检测nullCheck()// 8 类型检测与自动类型转换typeCheck();// 9 使用For循环useFor();// 10 使用while循环useWhile();// 11 使用when表达式val param = 1.2useWhen(param)// 12 使用区间useRange(8)useRange(14)useRange2()useRangeTravels()// 13 集合useCollection()// 14 创建类val person = Person("zhangsan",25)person.printPerson()
}class Person constructor(name:String,age:Int) {val mName = nameval mAge = agefun printPerson(){println("name is $mName, age is $mAge")}
}fun useCollection() {val list = listOf("a", "b", "c", "orange")// 第一种遍历for (item in list) {println(item)}// 第二种遍历list.forEach { println(it) }// 第三种遍历for (index in list.indices) {println(list[index])}// switch casewhen {"orange" in list -> println("juicy")"apple" in list -> println("apple is fine too")}// 使用 lambda 表达式来过滤(filter)与映射(map)集合:val fruits = listOf("banana", "avocado", "apple", "kiwifruit", "aaa")fruits.filter { it.startsWith("a") } // 过了所有以a开头的集合.sortedBy { it } // 排序.map { it.uppercase(Locale.getDefault()) }// 转化为大写.forEach { println(it) } // 输出
}fun useRangeTravels() {// 输出1-5for (x: Int in 1..5) {print(x)}println()// 输出13579for (x in 1..10 step 2) {print(x)}println()// 降序输出for (x in 9 downTo 0 step 3) {print(x)}
}fun useRange2() {// 创建 String数组val list = listOf("a", "b", "c")if (-1 !in 0..list.lastIndex) {println("-1 is out of range")}println("list.size = ${list.size}")println("list.indices = ${list.indices}")if (list.size !in list.indices) {println("list size is out of valid list indices range, too")}if (2 in list.indices) {println("2 is in valid list indices range")}
}// 使用 in 运算符来检测某个数字是否在指定区间内
fun useRange(i: Int) {if (i in 1..10) {println("fits in range")} else {println("not in range")}
}// kotlin 版本的switch case
fun useWhen(obj: Any) {when (obj) {1 -> println("One")"Hello" -> println("Greeting")is Long -> println("Long")!is String -> println("Not a string")else -> println("Unknown")}
}fun useWhile() {val items = listOf("apple", "banana", "kiwi")var index = 0while (index < items.size) {println("item at $index is ${items[index]}")index++}index = 0while (index in items.indices) {println("item at $index is ${items[index]}")index++}
}fun useFor() {// 增强for循环版本for1()// 角标访问版本for2()
}fun for1() {// 类似于// val items: List<String> = ArrayList(Arrays.asList("aaa", "bbb"))val items = listOf("apple", "banana", "kiwi")// kotlin中的遍历关键字in// 这里省略了item的声明for (item in items) {println(item)}
}fun for2() {val items = listOf("apple2", "banana2", "kiwi2")// 类似于使用角标访问数组for (index in items.indices) {println("item at $index is ${items[index]}")}
}//在使用is关键字内部 不需要再进行强制转换 在特定分支中 参数就是指定类型
fun typeCheck() {// kotlin 可以在方法中定义方法fun printLength1(obj: Any) {// 打印某个对象的字符串长度// ${getStringLength(obj) ?: "... err, not a string"} 花括号内是一个表达式// ?: 看起来是java三元操作符的简写 实际是个判空操作符 ?:前面的如果不是空 直接使用这个值 否则使用?:后面的值println(" $obj string length is ${getStringLength(obj) ?: "... err, not a string"} ")}printLength1("Incomprehensibilities")printLength1(1000)printLength1(listOf(Any()))
}fun getStringLength(obj: Any): Int? {// Any代表任意类型 相当于Java的Object// is 相当于Java中的instanceofif (obj is String) {// `obj` 在该条件分支内自动转换成 `String`类型return obj.length} // 在离开类型检测分支后,`obj` 仍然是 `Any` 类型return null
}fun nullCheck() {// 当某个变量的值可以为 null 的时候,必须在声明处的类型后添加 ? 来标识该引⽤可为空println("parseInt ==> " + stringToInteger("ww"))println("parseInt ==> " + stringToInteger("12"))printProduct("w", "2")
}// 使用?表明 返回值可能为空
fun stringToInteger(s: String): Int? {// 用到了Kotlin中使用try catchreturn try {Integer.valueOf(s)} catch (e: NumberFormatException) {null}
}fun printProduct(arg1: String, arg2: String) {val x = stringToInteger(arg1)val y = stringToInteger(arg2)// 直接使⽤ `x * y` 会导致编译错误, 因为它们可能为 nullif (x != null && y != null) {// 在空检测后, x 与 y 会⾃动转换为⾮空值(non-nullable)println(x * y)} else {println("'$arg1' or '$arg2' is not a number")}
}fun condition() {println("max is :" + maxOf(2, 3))println("max is :" + maxOf2(2, 3))
}fun maxOf(a: Int, b: Int): Int {if (a > b) {return a} else {return b}
}// 这里使用了第一节在函数时使用的简写
fun maxOf2(a: Int, b: Int) = if (a > b) a else b// const 代表运行时常量
// 这里是顶层
// 相当于 public static final double MY_CONSTANT
const val MY_CONSTANT = 3.1415fun variable() {// 变量声明的最常见方式// 变量 变量名:变量类型 = 赋值val a: Int = 1 // ⽴即赋值// 省略变量类型的声明 可以通过自动推断推断出类型val b = 2 // ⾃动推断出 `Int` 类型val c: Int // 如果没有初始值类型不能省略c = 3 // 明确赋值println(c)// 使用var来声明可变的变量var x = "String"println(x)x = "new String"println(x)// 使用val来声明不可变的变量 val有点像final关键字 但不完全相等val y = "String1111"//y = "new String1"//报错 Val cannot be reassigned// val 代表运行时常量// 相当于 final double PIval pi = 3.14println(pi)println(MY_CONSTANT)
}fun stringTemplate() {var a = 1// $a代表打印变量中的真实的值// 并且该次赋值以后 即使a的值变化了 s1的内容也不再变化val s1 = "a is $a"println(s1)// 给变量a赋值新值2a = 2// 输出 now a is 2 and s1 is a is 1println("now a is $a and s1 is $s1")// ${}内部是一个表达式 调用了 String的replace方法val s2 = "${s1.replace("is", "was")}, but now is $a"// 输出 a was 1, but now is 2println(s2)
}class D02Start {}

第二章 基础

知识点

章节:基本类型 包 控制流 返回与跳转

1. 基本类型 字面常量 显示转换 运算 数字比较 字符 布尔 数组 (⽆符号类型 跳过 因为他们似乎还不稳定) string

2.as 关键字

3.if 表达式  when 表达式 for 循环遍历 while 循环

4.return break continue的典型用法 学习使用标签 标签的隐式用法 返回标签时带有返回值

笔记

package com.example.lib.d02basic/*** 数据类型* Java中char可以与数字进行比较 但是Kotlin中不行* char a = 'a';* if (a>10) System.out.println(a);***/// 十进制
const val NUMBER1 = 123// 16进制的17
const val NUMBER2 = 0x11// 2进制的5
const val NUMBER3 = 0b0101
// Kotlin 不支持八进制fun main() {// 基本类型basicType()// 字面常量valVariable()// 显示转换explicitConvert()// 运算calculate()// 数字比较numberCompare()// 字符char()// 布尔bool();// 数组array()// ⽆符号类型 跳过 因为他们似乎还不稳定// Stringstring()
}fun string() {val string1: String = "This is String"// 利用for循环 输出字符串for (char in string1) {println(char)}println(string1)val s = "abc" + 1// 字符串拼接println(s + "def")// 与上面等价println("${s}def")val i = 10// 字符串模板println("i = $i")val s2 = "abc"// ⽤花括号括起来的任意表达式(花括号内部是一个表达式)println("$s2.length is ${s2.length}")val beef = "beef"val price = "99"println("$beef is $$price")
}fun array() {val arrayOfInt: IntArray = intArrayOf(1, 3, 5, 7, 9)// 创建⼀个 Array<String> 初始化为 ["0", "1", "3", "4", "5"]val asc = Array(5) { element -> element }// 利用数组自带的iterator遍历asc.forEach { println(it) }/**整型Int的数组*/arrayOfInt.forEach { println(it) }/**字符Char类型的数组*/val arrayOfChar: CharArray = charArrayOf('H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd')arrayOfChar.forEach { println(it) }/**字符串String数组*/val arrayOfString: Array<String> = arrayOf("Hello", "World")for (element in arrayOfString) {println(element)}// ⼤⼩为 5、 值为 [0, 0, 0, 0, 0] 的整型数组val arr1 = IntArray(5)arr1.forEach { print("$it ") }println()// 例如: ⽤常量初始化数组中的值// ⼤⼩为 5、 值为 [42, 42, 42, 42, 42] 的整型数组val arr2 = IntArray(5) { 42 }arr2.forEach { print("$it ") }println()// 例如: 使⽤ lambda 表达式初始化数组中的值// ⼤⼩为 5、 值为 [0, 1, 2, 3, 4] 的整型数组(值初始化为其索引值)val arr3 = IntArray(5) { it * 1 }arr3.forEach { print("$it ") }println()
}//三个引号"""括起来的字符串 内部没有转义并且可以包含换⾏以及任何其他字符
val definitionArray ="""
public class Array<T> {/*** 数组的定义类 摘自Array.kt*** Creates a new array with the specified [size], where each element is calculated by calling the specified* [init] function.* 创建一个指定长度的新数组 每一个元素可以被指定的init方法计算** The function [init] is called for each array element sequentially starting from the first one.* It should return the value for an array element given its index.* init方法被每一个元素从第一个元素开始依次调用 它应该返回元素下标的值*/public inline constructor(size: Int, init: (Int) -> T)/*** get方法 返回指定下标的元素* Returns the array element at the specified [index]. This method can be called using the* index operator.* ```* value = arr[index]* ```** If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException] except in Kotlin/JS* where the behavior is unspecified.*/public operator fun get(index: Int): T/*** set方法* Sets the array element at the specified [index] to the specified [value]. This method can* be called using the index operator.* ```* arr[index] = value* ```** If the [index] is out of bounds of this array, throws an [IndexOutOfBoundsException] except in Kotlin/JS* where the behavior is unspecified.*/public operator fun set(index: Int, value: T): Unit/*** 返回数组长度* Returns the number of elements in the array.*/public val size: Int/*** 创建用于遍历数组的迭代器* Creates an [Iterator] for iterating over the elements of the array.*/public operator fun iterator(): Iterator<T>
}
"""fun bool() {val a = trueval b = falseprintln(a || b)println(a && b)println(!a)
}fun char() {/*val a:Char = 'a'if (a == 1){ //Operator '==' cannot be applied to 'Char' and 'Int'}*/val b: Char = '1'println(b)//\t转义制表符//\b转义退格键//\n转义换行//\r转义回车符 不过没看懂效果。。//\'转义单引号//\"转义双引号//\\转义斜杠//\$转义美元符号val c: String = "aa \t bb\b cc\n dddddd \r ee \' ff \" gg\\ hh\$ "println(c)val d: Char = '5'println(decimalDigitValue(d))val e: Char = 'e'println(isSmallChar(e))val f: Char = 'F'println(isBigChar(f))
}fun decimalDigitValue(c: Char): Int {if (c !in '0'..'9') {throw IllegalArgumentException("Out of range")}return c.code - '0'.code // 利用数字在Unicode字符表里面的index位置 显式将char转换为数字
}fun isSmallChar(c: Char): Boolean {return c in 'a'..'z'
}fun isBigChar(c: Char): Boolean {return c in 'A'..'Z'
}fun numberCompare() {val a = 1.0val b = 2.0val c = 3.0println(a == b)println(a + b == c)println(a != b)println(a < b)println(a > b)println(a <= b)println(a >= b)// 上述几个比较操作符是所有数字类型通用的val e = 5println(e in 1..10)println(e !in 1..10)// in !in是区间判断符号 只能用在Int或者char数值上
}fun calculate() {val x = 5 / 2 // 与Java一样 整数相除还是整数 因此x是Int类型// println(x == 2.5) Operator '==' cannot be applied to 'Int' and 'Double'println(x == 2) // trueval y = 5L / 2 // Long 与 Int运算 得到Long类型println(y == 2L)val u = 5 / 2.0 // 自动推断类型为Doubleprintln(u == 2.5)val w = 5 / 2.toDouble() // 显示转换为Doubleprintln(w == 2.5)val v = 5 / 2f // 显示转换为floatprintln(v == 2.5f)// 位运算 对1 有符号左移2位 与上16进制的val b = 0b1100println(b)// 1 shl 2 = 0100// 1100 & 0100 == 0100val a = (1 shl 2) and bprintln(a)/**其他位运算shl(bits) – 有符号左移shr(bits) – 有符号右移ushr(bits) – ⽆符号右移and(bits) – 位与or(bits) – 位或xor(bits) – 位异或inv() – 位⾮*/
}fun explicitConvert() {/*val a: Int? = 1 // ⼀个装箱的 Int (java.lang.Integer)val b: Long? = a // 编译出错 无法将Int的对象赋值给Longval c: Long? = 1L // ⼀个装箱的 Long (java.lang.Long)val d: Int? = c // 编译出错 无法将Long的对象赋值给Int*//*以下为Java代码上面的Kotlin代码应该和当前的第一部分的Java Code类似Integer a = 1; // ⼀个装箱的 Int (java.lang.Integer)Long b = a; // 编译出错 无法将Int的对象赋值给LongLong c= 1L; // ⼀个装箱的 Long (java.lang.Long)Integer d= c; // 编译出错 无法将Long的对象赋值给Intint a = 1; // ⼀个装箱的 Int (java.lang.Integer)long b = a; // 可以编译long c= 1L; // ⼀个装箱的 Long (java.lang.Long)int d= c; // 编译出错 不能将long赋值给int*/val b: Byte = 1 // OK, 字⾯值是静态检测的// val i: Int = b // 错误 较⼩的类型不能隐式转换为较⼤的类型val i: Int = b.toInt() // OK: 显式拓宽println(i)/**每个数字类型⽀持如下的转换:toByte(): BytetoShort(): ShorttoInt(): InttoLong(): LongtoFloat(): FloattoDouble(): DoubletoChar(): Char*/// 虽然赋值和参数使用上没有隐式转换 但是算术运算会有重载做适当转换val l = 1L + 3 // Long + Int => Long 不会出错println(l)
}fun valVariable() {// 数字字⾯值中的下划线(⾃ 1.1 起)val oneMillion = 1_000_000val creditCardNumber = 1234_5678_9012_3456Lval socialSecurityNumber = 999_99_9999Lval hexBytes = 0xFF_EC_DE_5Eval bytes = 0b11010010_01101001_10010100_10010010// 定义一个Int值 为100val a: Int = -128// 定义一个可空的Int值 将a赋值给它val boxedA: Int? = a// 定义另一个可空的Int值 将a赋值给它val anotherBoxedA: Int? = a// 定义一个Int值 为10000val b: Int = 10000// 定义一个可空的Int值 将b赋值给它val boxedB: Int? = b// 定义另一个可空的Int值 将b赋值给它val anotherBoxedB: Int? = b// 这里涉及Kotlin中的==和===的差别// ==相当于java的equals// ===相当于java的== 是地址比较// 至于第一次输出是true 第二次是false 是因为Kotlin和Java一样 在内部保存了一些常量// 如果新创建的Integer 属于区间[-128,127] 则会从常量池取出数据赋值// 否则new一个新的Integer// 具体可以参照https://blog.csdn.net/jdsjlzx/article/details/106350713// 书里面的同⼀性应该指 地址比较相同// 相等性指他们的equals方法返回的结果println(boxedA === anotherBoxedA) // trueprintln(boxedB === anotherBoxedB) // falseprintln(boxedA == anotherBoxedA) // trueprintln(boxedB == anotherBoxedB) // true
}fun basicType() {// 未超出 Int 最⼤值的整型值初始化的变量都会推断为 Int 类型val one = 1 // Int// 如果初始值超过了其最⼤值,那么推断为 Long 类型val threeBillion = 3000000000 // Long// 显式指定 Long 型值val oneLong = 1L // Long// 显式指定 Byte 型值val oneByte: Byte = 1// 以⼩数初始化的变量,编译器会推断为 Double 类型val e = 2.7182818284 // Double// 显式指定为 Float 类型val eFloat = 2.7182818284f // Floatval eee = 2.7182818284f// 实际是Float 不会转换为double //Java中这么写 实际值是double类型 double myD = 2.7182818284f;fun printDouble(d: Double) {print(d)}// Kotlin 中的数字没有隐式拓宽转换val i = 1 // Int 类型val d = 1.1 // double 类型val f = 1.1f // float 类型printDouble(d)// printDouble(i) // 错误: 类型不匹配// printDouble(f) // 错误: 类型不匹配
}class D02Basic01BasicType {}
package com.example.lib.d02basic
// as 关键字
import java.io.File as MyFile // MyFile 代表“java.io.File”fun main() {val file = MyFile("filename")
//    val pa = MyPattern()val d03 = D02Basic02Package()
}class D02Basic02Package {}
package com.example.lib.d02basicfun main() {// if 表达式conditionIf()// when 表达式conditionWhen()// for 循环遍历conditionFor()// while 循环conditionWhile()
}fun conditionWhile() {testWhile()testDoWhile()
}fun testDoWhile() {var parameter = 5do {parameter--println(parameter)} while (parameter > 0)
}fun testWhile() {var parameter = 5while (parameter > 0) {parameter--println(parameter)}
}fun conditionFor() {val arrayOfString: Array<String> = arrayOf("Hello", "World","Kotlin")// 经典for循环classicTraverse(arrayOfString)// iterator遍历iteratorTraverse(arrayOfString)val arrayOfInt: IntArray = intArrayOf(11, 14, 17)// 区间表达式的for循环intervalExpressionTraverse()// 下标遍历indexTraverse(arrayOfString)// withIndex 遍历withIndexTraverse(arrayOfString)
}fun withIndexTraverse(arrayOfString: Array<String>) {for ((index, value) in arrayOfString.withIndex()) {println("the element at $index is $value")}
}fun indexTraverse(arrayOfString: Array<String>) {for (i in arrayOfString.indices) {println(arrayOfString[i])}
}fun intervalExpressionTraverse() {// 输出1 2 3for (element in 1..3) {println(element)}// 从6 降序到0 步长2 输出6 4 2 0for (i in 6 downTo 0 step 2) {println(i)}
}fun iteratorTraverse(arrayOfString: Array<String>) {val iterator =  arrayOfString.iterator()while (iterator.hasNext()){println(iterator.next())}
}fun classicTraverse(arr: Array<String>) {for (item in arr) {println(item)}
}// when 语句相当于Java中的switch case
fun conditionWhen() {// when 作为表达式使用println(expression(2))// when 作为表达式使用 所有分支已经覆盖可能结果println(expression2(false))// when 不作为作为表达式使用sentence(2)// when 表达式也可以将条件合并multiCondition(1)// 我们可以甚至可以用方法(⽽不只是常量)作为分⽀条件println(expressionAsCondition("hello"))println(expressionAsCondition("hello1"))// 我们可以⽤任意表达式(⽽不只是常量)作为分⽀条件expressionAsCondition2(11)expressionAsCondition2(1)// when里面的类型推断println(hasPrefix(1))println(hasPrefix("prefix"))// when 表达式是bool值boolWhen(1, 3)
}fun boolWhen(x: Int, y: Int) {when {isEven(x) -> println("x is isEven")isEven(y) -> println("y is isEven")else -> println("x y are Odd.")}
}fun isEven(x: Int): Boolean {return x % 2 == 0
}// 判断字符串是否以prefix打头
// 将when表达式的值直接赋值给方法返回值
fun hasPrefix(x: Any): Boolean = when (x) {// is String == true后 该分支里面 x是String类型的is String -> x.startsWith("prefix")else -> false
}fun expressionAsCondition(x: String): String {// 我们可以⽤任意表达式(甚至是方法作为分支条件 ⽽不只是常量)作为分⽀条件val str: String = "test"return when (x) {getResString(str) -> "greeting"else -> "none of the above"}
}fun getResString(param: String): String {return if (param == "test") {"hello"} else {"unknown"}
}val arrayOfInt: IntArray = intArrayOf(11, 14, 17)
fun expressionAsCondition2(x: Int) {// 我们可以⽤任意表达式(⽽不只是常量)作为分⽀条件when (x) {in 1..10 -> print("x is in the range")in arrayOfInt -> print("x is valid")!in 10..20 -> print("x is outside the range")else -> print("none of the above")}
}fun parseInt(s: String): Int {TODO("Not yet implemented")
}fun multiCondition(x: Any) {when (x) {// when 表达式也可以将条件合并0, 1 -> println("x == 0 or x == 1")else -> println("otherwise")}
}fun sentence(obj: Any) {// when 不作为作为表达式使用(不使用when的返回结果) 可以没有else分支when (obj) {1 -> println("x==1")2 -> println("x==2")}
}fun expression(obj: Any): String {// when 作为表达式使用(使用when的返回结果) 必须有else分支 除非所有分支已经覆盖可能结果return when (obj) {1 -> "x==1"2 -> "x==2"else -> { // 注意这个块"unknown"}}
}fun expression2(obj: Boolean): String {// when 作为表达式使用(使用when的返回结果) 必须有else分支 除非所有分支已经覆盖可能结果return when (obj) {true -> "true..."false -> "false..."}
}fun conditionIf() {// 传统⽤法val a = 10val b = 12var max1: Int = aif (a < b) max1 = b// With elseval max2: Intif (a > b) {max2 = a} else {max2 = b}// if本身是一个表达式 可以将他的结果传入参数val max3 = if (a > b) {println("Choose a")a} else {println("Choose b")b}// val max4 = if (condition) A else B// 如果condition成立 max4 = A 否则 max4 = Bprintln(max3)
}class D02Basic03Contrl {}
package com.example.lib.d02basic/*** Kotlin 有三种结构化跳转表达式:* return。默认从最直接包围它的函数或者匿名函数返回。* break。终⽌最直接包围它的循环。* continue。继续下⼀次最直接包围它的循环。*/fun main() {// 测试returntestReturn(null)testReturn("aa")// break continue的典型用法classicBreakContinue()// 学习使用标签testLabel()// testLabel1 vs testLabel2 标签的意义testLabel1()testLabel2()// 标签的隐式用法testLabel3()// testLabel3的另外一种写法testLabel4()// 模拟BreakmockBreak()// 返回标签时带有返回值println(returnLabel(listOf(1, 1, -1)))// 输出[]println(returnLabel(listOf(1, 0, 1)))// 输出[number 1, zero, number 1]
}/*** 该方法用于理解* 当要返⼀个回值的时候,解析器优先选⽤标签限制的 return,即* return@a 1* 意为“返回 1 到 @a ”,⽽不是“返回⼀个标签标注的表达式 (@a 1) ”。** 传入的参数里面只要有-1 就会返回空list 有0的则返回结果 不会出现"number 0"而是出现"zero"*/
fun returnLabel(ints: List<Int>): List<String> {return ints.map label@{if (it == 0) return@label "zero" // return at named label 返回到标签if (it == -1) return emptyList() // return at returnLabel 返回整个方法"number $it" // expression returned from lambda 返回的表达式}
}//foo(listOf(1, -1, 1)) // []
//foo(listOf(1, 0, 1)) // ["number 1", "zero", "number 1"]fun mockBreak() {// run:Calls the specified function block and returns its result.// run:调用指定方法块并返回其结果run loop@{listOf(1, 2, 3, 4, 5).forEach {if (it == 3) return@loop // 从传⼊ run 的 lambda 表达式⾮局部返回// 意思应该是返回到run方法调用处而不是退出整个方法 关系到print(" done with nested loop")能否被调用// 虽然break只能在循环中使用('break' and 'continue' are only allowed inside a loop) 在// 普通的代码中 用return+label的方式可以模拟break的作用println(it)}}print(" done with nested loop")
}fun testLabel1() {listOf(1, 2, 3, 4, 5).forEach {if (it == 3) return // ⾮局部直接返回到 foo() 的调⽤者 即跳出foo方法println(it)}println("this point is unreachable")
}fun testLabel2() {listOf(1, 2, 3, 4, 5).forEach lit@{// 声明标签if (it == 3) return@lit //使用标签 跳到声明标签的地方// 局部返回到该 lambda 表达式的调⽤者, 即 forEach 循环 而不是跳出整个方法 其实类似一个continue// 但是break和continue都是用在循环中的关键字 标签就起到替代作用print(it)}println(" done with explicit label")
}fun testLabel3() {listOf(1, 2, 3, 4, 5).forEach {// 省略了标签的声明if (it == 3) return@forEach // 局部返回到该 lambda 表达式的调⽤者, 即 forEach 循环// 常情况下使⽤隐式标签更⽅便。本例就是一个隐式标签 该标签与接受该 lambda 的函数同名print(it)}println(" done with implicit label")
}fun testLabel4() {listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {// 这里使用了匿名内部类替代lambda表达式// 因为return效果是推出函数执行体 那么这里的return只能跳出当前函数 起到的作用和上面一样 即一个continueif (value == 3) return // 局部返回到匿名函数的调⽤者, 即 forEach 循环print(value)})print(" done with anonymous function")
}fun classicBreakContinue() {for (i in 1..10) {if (i == 3) {continue // i 为 3 时跳过当前循环,继续下一次循环}println(i)if (i > 5) {break // i 为 6 时 跳出循环}}
}fun testLabel() {// 声明标签loop@ for (i in 1..100) {if (i == 10) break@loop //使用标签 跳到声明标签的地方 类似但不等价于C的gotoprintln(i)}
}fun testReturn(string: String?) {println("start=====")// ?:是一个二元表达式 如果 参数string==null 走前面的分支// 否则 走后面的分支val s = string ?: returnprintln(s)println("end=====")
}class D02Basic04BreakContinue {
}

Kotlin学习笔记 第一章开始 第二章 基础相关推荐

  1. Learning Perl学习笔记(1)第二章Scalar Data

    If Control Structure(IF循环) 脚本如下: #!/usr/bin/perl use warnings; use strict; use v5.24; my $line = < ...

  2. MYSQL学习笔记(自用) 第二章

    第二章 第一节. 内连接| Inner joins[在多张表格中检索数据] SELECT order_id, orders.customer_id, first_name, last_name FRO ...

  3. 【学习笔记】编译原理 第二章 文法和语言

    以下为参考课件与<编译技术>(张莉等著)的个人整理,若有错误欢迎指出 第二章 文法和语言 文章目录 第二章 文法和语言 一.文法的非形式讨论 二.文法的形式定义 1.文法的形式定义 2.推 ...

  4. 《计算机网络——谢希仁》学习笔记(6)~~第二章 2.3 2.4 2.5

    <<计算机网络(第7版)>>--谢希仁版本的学习笔记,分享给大家进行参考,希望大家指出不足之处 此书个人感觉第七,第八版相差不大,均可进行学习. ps:许多感觉比较细节的文字是 ...

  5. 深度学习笔记第一门课第二周:神经网络的编程基础(上)

    本文是吴恩达老师的深度学习课程[1]笔记部分. 作者:黄海广[2] 主要编写人员:黄海广.林兴木(第四所有底稿,第五课第一二周,第三周前三节).祝彦森:(第三课所有底稿).贺志尧(第五课第三周底稿). ...

  6. 深度学习笔记第一门课第二周:神经网络的编程基础(下)

    本文是吴恩达老师的深度学习课程[1]笔记部分. 作者:黄海广[2] 主要编写人员:黄海广.林兴木(第四所有底稿,第五课第一二周,第三周前三节).祝彦森:(第三课所有底稿).贺志尧(第五课第三周底稿). ...

  7. Kotlin学习笔记19 阶段复习1

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 基础部分 Kotlin学习笔记 第一章开始 第二章 基础_积跬步 至千里-CSDN博客 类与继承 Kotlin学习笔记 第 ...

  8. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引...

    Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引 原文:Introduction to 3 ...

  9. 《Go语言圣经》学习笔记 第一章 Go语言入门

    Go语言圣经学习笔记 第一章 Go语言入门 目录 Hello, World 命令行参数 查找重复的行 GIF动画 获取URL 并发获取多个URL Web服务 本章要点 注:学习<Go语言圣经&g ...

最新文章

  1. 【转载】Pytorch在加载模型参数时指定设备
  2. 漫画:原来,我是备胎!!!
  3. 无法从“const char [10]”转换为“char *”
  4. python工程师面试宝典_2019年,Python工程师必考的6个面试题,Python面试题No5
  5. 拥有触觉分析能力,上交MIT获IROS 2020最佳论文奖
  6. 怎样设置才能允许外网访问MySQL
  7. 语音社交app源码,更改ProgressBar颜色(圈圈)
  8. 【IT项目管理】第8章 习题
  9. 数据结构与算法分析——Hash表
  10. css样式怎么插入背景图片,css样式怎么插入背景图片?
  11. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Incorrect database name ‘dongdong_1
  12. 如何下载哔哩哔哩里的视频
  13. xshell中出现的绿色背景的文件夹
  14. npm ERR! nested aliases not supported 报错原因
  15. Python-Django毕业设计航空订票系统(程序+Lw)
  16. Bonjour(苹果电脑公司的服务器搜索协议商标名)
  17. python科学计算和可视化编程
  18. 基于深度学习的建筑能耗预测04——能耗建模
  19. python爬虫环境spider_Python爬虫Spider 一
  20. debian android环境搭建,Debian的安装和工作环境配置(zz)

热门文章

  1. curl txt批量_curl与wget高级用法
  2. Batch批量替换hosts
  3. manacher(马拉车)算法详解
  4. 【Python3爬虫】当爬虫碰到表单提交,有点意思
  5. 时域信号matlab实现
  6. 文件和目录操作命令(19 个)--14.dirname
  7. html5_canvas初学
  8. iOS 5.0.1完美越狱教程
  9. 2011年骑行爬山成绩记录
  10. mysqldump导出数据库视图_mysql中如何用mysqldump批量如何导出视图view啊?