学习笔记-Kotlin

准备工作

  1. 下载安装kotlin编译器,记录此笔记时的版本是v1.2.10,目前最新发布版本是v2.1.10
  2. 解压下载的安装包,配置环境变量指向bin目录(官方指导).

如果不想在本地安装环境,也可以使用在线编辑器

尝试编写第一个helloWorld

  1. 新建一个名为hello.kt的文件,内容如下:

    fun main(args: Array<String>) {
    println("Hello, World!")
    }

  2. 执行以下命令将kotlin编译生成jar:

    kotlinc hello.kt -include-runtime -d hello.jar

-d 参数用于指定生成的文件名. -include-runtime 参数指定将kotlin运行时需要的依赖库编译进包.

  1. 运行jar

    java -jar hello.jar

此时你可以看到命令窗口下出现了熟悉的"helloWorld!"

复制代码
Hello, World!

开发工具

  • IntelliJ IDEA 的Kotlin插件是和语言同步开发的,是可用功能最全的开发环境.InterlliJ IDEA15及以后的版本不需要额外设置,Kotlin插件可以开箱即用.你可以选择免费开源的IntelliJ IDEA Community 版,也可以选择IntelliJ IDEA Ultimate 版本.在"New Project"对话框中选择"Kotlin",然后就可以开始工作了.(参考材料:官方说明-内有下载链接)

  • 如果你用的是Android Studio,可以从"plug-in manager"(插件管理器)中安装Kotlin插件,打开"setting"(设置)=>"Plugins"(插件)=>"Install JetBrains Plugin"(安装JetBrains插件)=>"Kotlin",就可以开始工作啦.

  • Eclipse同样可以使用kotlin,Kotlin的Eclipse插件提供了必要的IDE功能,如导航和代码补全.可以通过Eclipse Marketplace中找到,选择"Help"=>"Eclipse Marketplace",搜索"kotlin"即可.

  • 最简单的方式,就是直接使用在线playground ,不需要安装任何环境和配置就可以在线编写编译及运行Kotlin小程序.在线playground

基本语法差异(与java对比)

  • 声明一个函数使用关键字:fun,如上面的helloWorld.
  • 数组就是类,Kotlin没有声明数组类型的特殊语法.如:Array<String>
  • println代替了System.out.println.
  • 代码行结尾不需要;.
  • 参数及类型用:隔开,函数返回类型写在参数列表之后.如:fun max(a:int,b:int):Int{.

变量

定义变量使用关键字+变量名+类型(也可不加).

如:

复制代码
val question = "The Ultimate Question of Life,the Universe,andEverything"
var answer = 42
var answer: Int //如果没有初始化,要显示指定类型.

如果你不指定类型,编译器会自动分析初始经表达式的值,自动推导出变量类型.

可变变量和不可变变量

  • val:不可变引用,对应java的final. --应尽可能地使用它来场景所有的kotlin变量.

尽管val引用自身是不可变的,但它指向的对象可能是可变的.如:

复制代码
var languages = arrayListOf("Java")
languages.add("Kotlin")
  • var:可变引用.

字符串模板

先看个例子:

复制代码
fun main(args:Array<String>){
    val name = if(args.size > 0) args[0] else "Kotlin"
    println("Hello,$name!")
}

以上使用了$字符将变量转义输出,等效于java中的:

复制代码
"Hello,"+name+"!"

如果需要在字符串中输出*$*字符,需要对它进行转义,如:

复制代码
println("\$x")

将会输出:

复制代码
$x

涉及较复杂的表达式时,需要将表达式用{}括起来:

复制代码
println("Hello,${args[0]}!")

在花括号内,还可以嵌套使用双引号

复制代码
println("Hello,${if(args.size>0) args[0] else "someone"}!")

类和属性

类中声明只读属性和可写属性使用关键字valvar来区分:

复制代码
class Person(
    val name : String,// 只读属性,生成一个字段和一个简单的getter
    var isMarried: Boolean //可写属性,生成一个字符,一个getter和一个setter
)

使用属性:

复制代码
fun main(args: Array<String>) {
    println("Hello, world!")
    val person = Person("lqq",true) //调用构造方法不需要使用new关键字
    println("Hello,"+person.name) //可以直接访问属性,但实际调用的是getter
    println("Hello,${person.name}!")
}

自定义访问器:

复制代码
fun main(args: Array<String>) {
    val rec = Rectangle(3,3)
    println(rec.isSquare)
}

class Rectangle(val height: Int, val width: Int){
    val isSquare: Boolean
    get(){
        return height == width
    }
    
    //也可以写为:
    //get() = height == width
}

目录和包

  • Kotlin不区分导入的是类还是函数,可以直接导入函数

    package geometry.example
    import geometry.shaes.createRandomRectangle

    fun main(args: Array<String>){
    println(createRandomRectangl().isSquare)
    }

  • 包层级结构可以不需要遵循目录层级结构

    geometry
    |--example.kt <=包geometry.example
    |--shapes.kt <=包geometry.shapes

表示和处理选择

枚举

Kotlin中这是极少数比Java使用了更多关键字的例子,使用了enumclass两个关键字:

复制代码
enum class Color{
    RED,ORANGE,YELLOW,GREEN
}

声明一个带属性的枚举类

复制代码
enum class Color(
    val r: Int,val g: Int,val b: Int){
    RED(255,0,0),ORANGE(255,165,0),
    YELLOW(255,255,0); //这里必须要有分号,这是Kotlin语法中唯一必须使用分号的地方.

    fun rgb() = (r*256+g)*256+b //给枚举定义一个方法
}

when

使用when来处理枚举类.

与Java不同,不需要为每个分支都写上break语句.

复制代码
fun getMnemonic(color:Color) =  //直接返回一个when表达式
    when(color){  //如果颜色和枚举常量相等就返回对应字符串
        Color.RED -> "Richard"
        Color.ORANGE -> "OF"
        Color.YELLOW -> "York"
        Color.GREEN -> "Gave"
        Color.BLUE -> "Battle"
        ...
    }

>>> println(geMnemonic(Color.BLUE))
Battle

一个分支上合并多个选项,只需要用,隔开

复制代码
fun getWarmth(color:Color) = when(color){
    Color.RED,Color.ORANGE ->"warm"
    Color.GREEN -> "neutral"
}

when中使用任意对象

复制代码
fun mix(c1:Color,c2:Color)=
when(setOf(c1,c2)){
    setOf(RED,YELLOW) -> ORANGE
    setOf(YELLOW,BLUE) -> GREEN
    else -> throw Exception("Dirty color")
}

以上模拟了调色板的方法,当调用参数与分支条件相等时可以得到对应的返回.都不满足时返回返回else分支结果.

以上写法也可以改为不带参数的when(优点:不会创建额外对象,但会更难理解):

复制代码
fun mix(c1:Color,c2:Color)=
when{
    (c1 == RED  && c2 == YELLOW) || c1 == YELLOW && C2 == RED -> ORANGE
    else -> throw Exception("Dirty color")
}

智能转换

在Java中,需要通过instanceOf来检查一个变量是否属于某个类型,使用时还需要显示的转换,如:

复制代码
if( e instanceOf Sum){
  Sum s = (Sum)e;
  return s.left;
}

而在kotlin中,通过一次is检查后,即可直接使用(编译器自动执行了类型转换):

复制代码
if(e is Sum){
    return e.left
}

代码块做为"if"和"when"的分支

ifwhen都可以使用代码块作为分支体.在这种情况下,代码块中的最后一个表达式就是返回的结果.

复制代码
fun evalWithLoggin(e:Expr):Int = 
    when(e){
    	is Num ->{
    		println("num:${e.value}")
    		e.value //如果e的类型是Num就会返回这个表达式
    	}
    	is Sum ->{
    		val left = evalWithLogging(e.left)
    		val right = evalWithLogging(e.right)
    		left+right //如果e的类型为Sum就会返回这个表达式
    	}
    	else -> throw IllegalArgumentException("Unknown expression")
    }

迭代数字:区间和数列

kotlin中可以使用..来表示区间

复制代码
//闭区间
for(i in 1..100){
	println(i)
}

//补充:开区间
for(i in 0 until 10){
	println(i)
}

倒序迭代:

复制代码
for(i in 100 downTo 1 step 2){
	println(i)
}
相关推荐
Kapaseker2 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
A0微声z3 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin
alexhilton4 天前
使用FunctionGemma进行设备端函数调用
android·kotlin·android jetpack
lhDream4 天前
Kotlin 开发者必看!JetBrains 开源 LLM 框架 Koog 快速上手指南(含示例)
kotlin
RdoZam4 天前
Android-封装基类Activity\Fragment,从0到1记录
android·kotlin
Kapaseker4 天前
研究表明,开发者对Kotlin集合的了解不到 20%
android·kotlin
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
starlaky5 天前
Django入门笔记
笔记·django
勇气要爆发5 天前
吴恩达《LangChain LLM 应用开发精读笔记》1-Introduction_介绍
笔记·langchain·吴恩达