【Kotlin】官网学习笔记
0、IDEA环境设置:
1、基础语法 BasicSyntax
地址:https://kotlinlang.org/docs/basic-syntax.html
一、方法与变量
可以直接编写main方法执行
1 2 3 | fun main() { println( "Hello world!" ) } |
获取main方法的参数并打印:
1 2 3 | fun main(args : Array<String>) { println(args.contentToString()) } |
完整的方法声明:
1 2 3 | fun sum(a : Int, b : Int) : Int { return a + b } |
支持模版语法(提取单个变量,或者是一个表达式)嵌入字符串值:
1 2 3 | fun printSum(a : Int, b : Int) : Unit { println( "sum of $a and $b is ${a + b}" ) } |
变量声明可以完整声明,也可以类型推断
1 2 | val a : Int = 1 // immediate assignment val b = 2 // `Int` type is inferred |
二、类和实例
使用class定义一个Kt类:
1 | class Shape |
kt类没有构造器,直接声明在类上表示需要实例需要构建参数
1 2 3 | class Rectangle( var height : Double, var length : Double) { var perimeter = (height + length) * 2 } |
kt的实例的创建是直接调用类名和参数注入获取:
1 2 | val rectangle = Rectangle( 5.0 , 2.0 ) println( "The perimeter is ${rectangle.perimeter}" ) |
三、循环与分支判断:
if 和 else 通用判断:
1 2 3 4 5 6 7 | fun maxOf(a : Int, b : Int) : Int { if (a > b) { return a } else { return b } } |
可以简单描述行为, 方法的返回类型根据表达式进行自动推断:
1 | fun maxOf(a : Int, b : Int) = if (a > b) a else b |
使用for循环数组的元素:
1 2 3 4 | val items = listOf( "apple" , "banana" , "kiwifruit" ) for (item in items) { println(item) } |
或者循环的是数组的下标,可以通过下标获取元素:
1 2 3 4 | val items = listOf( "apple" , "banana" , "kiwifruit" ) for (index in items.indices) { println( "item at $index is ${items[index]}" ) } |
While循环:
1 2 3 4 5 6 | val items = listOf( "apple" , "banana" , "kiwifruit" ) var index = 0 while (index < items.size) { println( "item at $index is ${items[index]}" ) index++ } |
kt使用When表达式来代替switch case语法:
对象可以作为when的入参,提供值或者表达式进行判断,条件成立时执行箭头后的内容
类似else if 执行首个成立的条件后,后续情况不执行
当所有条件都不成立之后走else处理
1 2 3 4 5 6 7 8 | fun describe(obj : Any) : String = when (obj) { 1 -> "One" "Hello" -> "Greeting" is Long -> "Long" !is String -> "Not a string" else -> "Unknown" } |
使用in关键字判断是否在一个范围中:
判断变量x 是否在 1 到 变量y + 1这个范围中
1 2 3 4 5 | val x = 10 val y = 9 if (x in 1 ..y+ 1 ) { println( "fits in range" ) } |
范围需要声明起始值和结束值,可以使用变量或者表达式:
另外也可以对in进行取反,表示不在这个范围之内
1 2 3 4 5 6 7 8 | val list = listOf( "a" , "b" , "c" ) if (- 1 !in 0 ..list.lastIndex) { println( "-1 is out of range" ) } if (list.size !in list.indices) { println( "list size is out of valid list indices range, too" ) } |
可以设置范围的迭代顺序,或者是调整步进值
1 2 3 4 5 6 7 | for (x in 1 .. 10 step 2 ) { print(x) } println() for (x in 9 downTo 0 step 3 ) { print(x) } |
四、集合操作:
list集合使用stream语法更简洁
1 2 3 4 5 6 | val fruits = listOf( "banana" , "avocado" , "apple" , "kiwifruit" ) fruits .filter { it.startsWith( "a" ) } .sortedBy { it } .map { it.uppercase() } .forEach { println(it) } |
五、类型检查
使用is关键字对值进行类型匹配判断
1 2 3 4 5 6 7 8 9 | fun getStringLength(obj : Any) : Int? { if (obj is String) { // `obj` is automatically cast to `String` in this branch return obj.length } // `obj` is still of type `Any` outside of the type-checked branch return null } |
2、编码风格 Idioms
地址:https://kotlinlang.org/docs/idioms.html
一、数据模型类的用法:
详细文档:https://kotlinlang.org/docs/data-classes.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* 数据模型类的用法 */ data class Customer 2 ( val name : String, val email : String) fun main() { /* 相同属性的对象,Kt不会重新创建? hashCode值是一样的 */ val customer 2 = Customer 2 ( "李四" , "1791255334@qq.com" ) val sameOne = Customer 2 ( "李四" , "1791255334@qq.com" ) /* 提供以下默认方法: copy(), hashCode(), equals(), toString(), component() */ /* 默认的转字符串方法 */ val toString = customer 2 .toString() println(toString) /* component对应属性值 */ val component 1 = customer 2 .component 1 () val component 2 = customer 2 .component 2 () println( "component1 -> $component1, component2 -> $component2" ) val copiedCustomer 1 = customer 2 .copy() val copiedCustomer 2 = customer 2 .copy( "王五" , "1417274225@qq.com" ) val copiedCustomer 3 = customer 2 .copy(name = "赵六" ) println( "c1 -> ${customer2.hashCode()}, sameOne -> ${sameOne.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer1)}" ) println( "c2 -> ${copiedCustomer1.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer1)}" ) println( "c3 -> ${copiedCustomer2.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer2)}" ) println( "c4 -> ${copiedCustomer3.hashCode()}, isEquals c1 ? ${customer2.equals(copiedCustomer3)}" ) /* 支持解构语法 */ val (name, email) = copiedCustomer 3 println( "名称:$name,邮箱:$email" ) } |
打印结果:
1 2 3 4 5 6 7 8 9 | Customer 2 (name = 李四, email = 1791255334 @ qq.com) component 1 -> 李四, component 2 -> 1791255334 @ qq.com c 1 -> 1965046214 , sameOne -> 1965046214 , isEquals c 1 ? true c 2 -> 1965046214 , isEquals c 1 ? true c 3 -> - 1497309957 , isEquals c 1 ? false c 4 -> 1974389211 , isEquals c 1 ? false 名称:赵六,邮箱: 1791255334 @ qq.com Process finished with exit code 0 |
二、方法可设置默认参数
1 2 3 4 5 6 7 8 9 | fun main() { /* 方法参数支持声明默认值,在调用时可以不需要提供参数 */ defaultParamFun() } fun defaultParamFun(a : Int = 0 , b : String = "" ) { println( "a is $a, b is $b" ) } |
调用结果:
1 | a is 0 , b is hello |
三、过滤逻辑与隐式参数
详细文档见:https://kotlinlang.org/docs/java-to-kotlin-collections-guide.html#filter-elements
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | fun main() { val list = listOf( 1 , 2 , 3 , 4 , 5 , 6 ) /* 1、支持lambda编写过滤逻辑 */ val positives 1 = list.filter { x -> x > 0 } /* 2、或者调用隐式参数it编写过滤逻辑 */ val positives 2 = list.filter { it > 0 } println( "p1 -> $positives1, p2 -> $positives2" ) /* 3、map类型可以同时对key和value编写过滤逻辑 */ val numbers = mapOf( "key1" to 1 , "key2" to 2 , "key3" to 3 , "key11" to 11 ) val filteredNumbers = numbers.filter { (key, value) -> key.endsWith( "1" ) && value > 10 } println(filteredNumbers) /* 4、KT支持对元素的类型进行过滤 */ val numbers 2 = listOf( null , 1 , "two" , 3.0 , "four" ) println( "All String elements in upper case:" ) /* filterIsInstance指定了泛型的类型后,自动过滤非泛型类型的元素 */ numbers 2 .filterIsInstance<String>().forEach { println(it.toUpperCase()) } /* 5、逻辑检验 */ val numbers 3 = listOf( "one" , "two" , "three" , "four" ) println(numbers 3 .none { it.endsWith( "e" ) }) println(numbers 3 .any { it.endsWith( "e" ) }) println(numbers 3 .all { it.endsWith( "e" ) }) } |
四、IN关键字判断
1 2 3 4 5 6 7 8 | fun main() { /* in 判断 */ val johnEmail = "john@example.com" val emailsList = listOf( "1791255334@qq.com" , "1791255331@qq.com" , "1791255337@qq.com" , johnEmail) if (johnEmail in emailsList) println( "$johnEmail is in emailsList!" ) /* 或者取反判断 */ if (johnEmail !in emailsList) println( "$johnEmail is not in emailsList!" ) } |
五、字符串操作:
详细文档:https://kotlinlang.org/docs/java-to-kotlin-idioms-strings.html#concatenate-strings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | import kotlin.random.Random fun main() { val a = 100 /* 1、 改用模版语法实现 */ println( "$a: dsada" ) /* 2、可以对字符串逐个字符遍历 */ val str = "abcd" for (c in str) println(c) /* 3、模版语法提供了两种用法 [变量引用] $var 和 [表达式引用] ${var} */ println( "变量引用式:$a, 表达式引用式:${a + 100}" ) /* 3.1、对模版语法本身需要展示$字符时使用表达式来占位 */ println( "${'$'}_9.99" ) /* 4、KT允许Java方式的字符拼接,但是要求必须是首个变量类型是字符串 */ val newStr = str + "1334" /* 不可以 val newStr = 100 + str 这样使用 */ println(newStr) /* 5、支持字符逃逸符号 */ val s = "Hello, world!\n" println( "s -> $s" ) /* 6、原始字符串编写 */ var text = "" " for (c in " foo ") print(c) " "" println( "text -> \n$text" ) /* 7、原始字符串存在前导留白内容,可以使用trimMargin方法处理, 该方法需要提供留白结束符号标记 */ text = "" " |Tell me and I forget. |Teach me and I remember. |Involve me and I learn. |(Benjamin Franklin) " "" .trimMargin( "|" ) println( "text -> \n$text" ) /* 8、调用转大写方法 */ val toUpperCase = str.toUpperCase() println(toUpperCase) /* 9、KT使用字符构建拼接语法: */ val countDown = buildString { for (i in 5 downTo 1 ) { append(i) appendln() } } println(countDown) /* 10、将集合元素合并成字符串 */ val numbers = listOf( 1 , 2 , 3 , 4 , 5 , 6 ) val invertedOddNumbers = numbers .filter { it % 2 ! = 0 } .joinToString(separator = ";" ) { "${-it}" } println(invertedOddNumbers) /* 11、调用isBlank方法判断是否为空串,然后返回一个默认值 */ val name = getName().ifBlank { "John Doe" } println(name) /* 12、替换字符串,常用于清除目标字符,KT单独提供一个API实现 */ var input = "##place##holder##" val result = input.removeSurrounding( "##" ) println(result) /* 13、正则替换出现数值的字符 */ val regex = Regex( "" "\w*\d+\w*" "" ) // raw string input = "login: Pokemon5, password: 1q2w3e4r5t" val replacementResult = regex.replace(input, replacement = "xxx" ) println( "Initial input: '$input'" ) println( "Anonymized input: '$replacementResult'" ) /* 15、KT对点号不需要转义 */ val split = "Sometimes.text.should.be.split" .split( "." ) println(split) /* 16、字符截取, KT提供了更为简便的API,不通过下标入参,提供指定字符实现 */ val inputs = "What is the answer to the Ultimate Question of Life, the Universe, and Everything? 42" val answer = inputs.substringAfter( "?" ) println(answer) val inputs 2 = "To be, or not to be, that is the question." val question = inputs 2 .substringAfterLast( "," ) println(question) /* 17、缩进处理 */ val result 2 = "" " Kotlin Java " "" .trimIndent() println(result 2 ) } fun getName() : String = if (Random.nextBoolean()) "" else "David" |
六、设置扩展方法:
1 2 3 4 5 6 7 8 9 | fun main() { /* 扩展方法测试 */ "这是一串字符" .testFun() } /* 可以声明扩展方法 */ fun String.testFun() { println( "测试方法调用! 打印字符本体[$this]" ) } |
七、创建一个单例对象:
1 2 3 4 5 6 7 8 9 10 11 | fun main() { println( "instance -> $Resource, name -> ${Resource.name}" ) } /* 声明一个单例对象 */ object Resource { const val name = "Name" } 打印结果 instance -> Resource @ 330 bedb 4 , name -> Name |
八、创建抽象类的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | abstract class MyAbstractClass { abstract fun doSomething() abstract fun sleep() } fun main() { val myObject = object : MyAbstractClass() { override fun doSomething() { // ... println( "todo doSomething" ) } override fun sleep() { // ... println( "todo sleep" ) } } myObject.doSomething() } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2021-01-19 【Dos-BatchPrograming】04
2021-01-19 【Dos-BatchPrograming】03