Kotlin

学习Kotin基础语法(大概

在公司我最喜欢的人是食堂阿姨,每次跟她说谢谢她都很热情的回复,很有情绪价值
我为啥要把这个写在最前面

下载Android Studio。。我又想起来上学期和舍友做小组作业怎么都搞不定那个gradle的下载

D老师告诉我的话我会用 引用 蓝色表示。(还有我自己的粉色

好消息是我现在会改颜色了 2026-07-14 17:09:50 星期二
f1a5bd-粉色
8a9bd3-蓝色

2026-07-15 09:22:52 星期三
图片来自网络/菜鸟教程


我突然想到书写代码的规范标准,写在最前面
函数调用括号()等,不要和前面的名字加空格。
比如 prinlin()
但是for、if、when后面+空格=(


  • 包声明
    image
    Kotlin源文件不需要匹配的目录和包,源文件可以放在任何文件目录。
    以上例子中test()的全名是com.runoob.test
    Runoob的全名是com.runoob.main.Runoob
    如果没有指定包,默认为defalut包

  • 默认导入
    就。。。很多。。。你懂吧
    不知道有啥用

  • 函数定义(重要)

  1. 函数定义使用关键字fun

参数:类型
输入进来的:吐出去的
image

  1. 表达式作为函数体,返回类型自动推断
    image
    两行代码功能上一样,都是求和
    表达式:几个数字的运算或逻辑
    public函数是公开的,其他文件或模块都能调用,为了保证稳定性,规定好返回类型

  2. 无返回值的函数(类似Java中的void)
    image
    这个没啥可说的吧,返回unit类型,可以省略不写

我现在非常的困,还有60分钟下班,今天真的没学什么呀,我把原因都归咎于这个键盘太烂了,等我买的迈从到了我一定要好好学习

可变长参数函数(如何断句)
函数的变长参数可以用vararg关键字进行标识

vararg可以理解成”参数的打包器 “ 调用时可以塞进去很多同类型的数字,函数内部会自动把他们打包成一个数组来处理

  • 一个函数只能有一个vararg参数
  • 如果函数还有别的普通参数,vararg必须排在最后面

如果没有这个关键字,想传入不确定个数的数字,要自己建一个数组,再把数组传进去

2026-07-14 17:39:04 星期二
lambda(匿名参数)

这个匿名函数有点像嵌套函数。
比如 f(z) z = x + y
匿名参数就是f(x + y)。你不用给它起一个名字z
image
可随身携带的计算器

  • 我定义了一个变量(盒子)叫sumLambda
  • 这个变量的标签上写着:这个盒子里装的东西,必须能接收两个Int,并且吐出一个Int
  • 最后是内部计算器逻辑
  • x,y -> 代表我要往里放两个数字 x和y
  • x + y是运算结果,这个{}里的代码块会把xy加起来,然后自动吐出去

下班了~~~~


2026-07-15 09:12:23 星期三
上班了image
我写的这个日记居然有两个人看我不行了吧

如果窗口顶部没有空白区域供鼠标拖动,使用
ALT+空格+M

  • 定义常量与变量
    (我觉得应该先学这里吧)

var <标识符> : <类型> = <初始化值> 可变
val <标识符> : <类型> = <初始化值> 不可变

  1. 常量与变量都可以没有初始化值,但是在引用前必须初始化
  2. 编译器支持自动类型判断,声明时可以不指定类型,由编译器判断(如果初始化的时候没赋值就不可以
    image
  • 注释(允许嵌套)
    // 单行
    /* 多行 */

  • 字符串模板
    $ 表示一个变量名或变量值
    $varName 表示变量值
    ${varName.fun()} 表示变量的方法返回值
    好像懂了,又好像没懂,反正我在idea里试了一下
    执行代码要在函数里写
    声明才能写前面

    image
    image

2026-07-15 10:12:21 星期三

  • NULL检查机制
    类型后面加?表示可空
    var age: String? = "23"
    (现在不是空的,以后有可能变成空的)
    现在要把盒子里的文本23变成数字23
    调用.toInt()
    如果盒子是空的,强行拆就会爆炸
    下面是三种处理方式
  1. 强行拆
    val ages = age!!.toInt()
    有可能会爆炸,百分百确定不是空的才可以
  2. 试探一下
    val ages1 = age?.toInt()
    如果里面有东西,就正常
    如果里面没东西,就不执行.toInt(),并把null赋值给ages1
  3. 空了就用备胎
    val ages2 = age?.toInt() ?: -1
    先试探,如果有就拿23
    如果空,就拿-1

2026-07-15 10:51:55 星期三
刚才帮我朋友干活了,现在继续学习

  • 类型检测及自动转换类型
    可以使用is运算符检测一个对象是否是指定类型的实例

    插播:
    类 = 饼干模具
    对象 = 做出来的饼干
    实例 = “这块饼干是这个模具做出来的”这个关系

fun main() {
    val obj: Any = "Hello, Kotlin"

    if (obj is String) {
        println("字符串长度: ${obj.length}")
    } else {
        println("不是字符串类型")
    }
}
  1. 第四行is检测通过,kotlin会记住obj是String类型,所以后面可以直接访问String的属性和方法
    如果没有进行这一步是不可以用.length的
    出了if语句后,obj又变回了any
  2. 类似的还有 !is
  3. 运算符&&左边进行了is检测,右边就可以用String的属性和方法了
  • 区间
    区间表达式由具有操作符形式..的rangeTo函数辅以in和!in形成

2026-07-15 11:26:32 星期三
吃饭了

2026-07-15 13:14:10 星期三
学习了

示例:

for (i in 1..4) print(i) //输出“1234”
for (i in 4..1) print(i)//什么都不输出
//降序要用downTo

if (i in 1..10){
    println(i)
}

//使用step指定步长
for (i in 1..4 step 2) print(i)// 输出1和3

for (i in 4 downTo 1 step 2) print(i)

//使用 until 函数排除结束元素
for (i in 1 until 10){//排除了10
     println(i)
}

Kotlin 基本数据类型

  • 整数类型
  1. Byte:8位,范围从-128到127
  2. Short:16位,范围从-32768到32767
  3. Int:32位,范围从从-2³¹到2³¹-1
  4. Long:64位,范围从-2的63次幂到2的63次幂-1
  • 浮点数类型
  1. Float:32位,带有6-7位有效数字
  2. Double:64位,带有15-16位有效数字
  • 字符类型
    Char:16位的Unicode字符
  • 布尔类型
    Boolean:有两个值。true和false
  • 字符串类型
    String:一系列字符的序列
  • 数组类型
  1. IntArray:存储Int类型的数组
  2. DoubleArray:存储Double类型的数组
  3. Array:泛型数组,可以存储任意类型
  • 字面常量
  1. 十进制:123
  2. 长整型以大写的L结尾:123L
  3. 16进制以0x开头:0x0F
  4. 2进制以0b开头:0b00001011
  5. 8进制不支持
    后面不想写了好累
  • 比较两个数字
  1. 类型转换:Kotlin在比较不同数据类型时会自动进行类型转换。比如a和c比较,a是Int类型,b是Double类型,Kotlin会自动将a转换成为Double类型进行比较。
    转换的规则就是小的变大(和下面说的那个转换应该不太一样)
  2. 相等性:==运算符用于值的比较。===用于地址的比较。一般使用==
    例如:xy的值相等,但是x===y一定返回false,因为它们是不同的实例
  • 类型转换
    不能把Byte型值赋给一个Int变量
val b: Byte = 1
val i: Int = b //错误

可以用toInt()方法

val b: Byte = 1
val i: Int = b.toInt()

要转换成什么就to什么()
有些情况下可以自动转换,前提是可以根据上下文环境推断出正确的数据类型,而且教学操作符会做出相应的重载。

  • 位操作符
    这个先不看了,D老师告诉我用不到

  • 字符
    就是char类型不能直接和数字操作,Char必须是用单引号'包含起来的。还有一点转义字符的用到了再说吧

2026-07-15 15:00:03 星期三
image破键盘

  • 布尔
    || 或
    && 与
    !非

  • 数组
    数组的两种创建方式

    fun main(args: Array<String>){
	//[1, 2, 3]
	val a = arrayOf(1, 2, 3)
	//[0, 2, 4]
	val b = Array(3, { i -> (i * 2) })
	//0x2, 1x2, 2x2
    }

除了类Array还有ByteArray, ShortArray等。效率更高

  • 字符串
  1. String是不可变的
  2. Kotlin支持三个引号"""括起来的字符串,支持多行字符串
  3. String可以通过trimMargin()方法来删除多余的空白

我感觉我刚才玩了好久的手机!
image
剩下的一个半小时要努力学习啊
2026-07-15 16:20:52 星期三

  • 字符串模板
    字符串可以包含模板表达式,即一小段代码,会求值并把结果合并到字符串中。模板表达式以美元($)开头,由一个简单名字构成
    fun main(args: Array<String>){
	val s = "runoob"
	val str = "$s.length is ${s.length}"
	println(str)
	//求值结果为"runoob.length is 6"     
	}

啊啊没有学习,玩了很久的手机
下班吧。。。淡淡的

2026-07-16 13:08:32 星期四
上午公司断网了,没学习。现在开始
今天我的搭子没来上班
image

Kotlin条件控制

  • IF表达式
    一个if语句包含一个布尔表达式和一条或多条语句。
val c = if (condition) a else b 
// condition部分自己填条件
  • when语句
    看了一下比较简单,贴一段例子知道格式就好
    when (x){
	1 -> print("x == 1")
	2 -> print("x == 2")
	else -> {    //我没懂这里加括号干啥
		print("x不是1,也不是2")
		}
	}

还可以取代if-else链
image
image


Kotlin循环控制

  • FOR循环
    通过索引遍历一个数组或者list
    image
    image
    items.indices返回该集合(或数组)的“有效索引范围”。
    返回的是 0 到items.size - 1

  • while与do...while循环
    do...while 和while循环相似
    但是do...while至少循环一次
    跟java一样

  • 返回和跳转

  1. return 默认从最直接包围它的函数或者匿名函数返回。
  2. break 终止最直接包围它的循环
  3. continue 继续下一次最直接包围它的循环
  • Break和Continue标签
    任何表达式都可以用标签来标记。
    标签的格式为标识符后跟@符号
    例如:abc@、fooBar@。
    可以用标签限制break或continue

  • 标签处返回
    没看懂,还有什么内连非内连的。交给idea吧

类的属性

  • 属性定义
    kotlin中没有new关键字

怎么新建类的对象

val person: Person = Person()
//省略后
val person = Person()
  1. 主构造器长什么样(“类头部”)
    主构造器就是类名称后面的部分
//完整写法:class 类名 constructor(参数列表){}
class Person Constructor(firstName: String){

}

创建对象时(比如Person("张三"),张三就会传给firstName

  1. 什么时候不能省略constructor
    平常大多数情况都可以省略,不能省略如下:
  • 加了注释(@Inject)
  • 构造器是私有的,有private
    上面这些关键字都是加在constructor前面的

2026-07-17 09:04:29 星期五
上班了
image

  • getter和setter
    属性声明getter和setter都是可选的
    val不允许设置setter函数,因为是只读的
    然后也是没怎么看懂

  • 实例
    getter和setter来了,刚才没看懂现在可以了

class Person {

    var lastName: String = "zhang"
        get() = field.toUpperCase()   // 将变量赋值后转换为大写
        set
//重写了getter,调用这个值的时候全变成大写


    var no: Int = 100
        get() = field                // 后端变量
        set(value) {
            if (value < 10) {       // 如果传入的值小于 10 返回该值
                field = value
            } else {
                field = -1         // 如果传入的值大于等于 10 返回 -1
            }
        }
		
//重写了setter

    var heiht: Float = 145.4f
        private set
}

// 测试
fun main(args: Array<String>) {
    var person: Person = Person()

    person.lastName = "wang"

    println("lastName:${person.lastName}")

    person.no = 9
    println("no:${person.no}")

    person.no = 20
    println("no:${person.no}")

}

输出结果
image
只能在访问器(getter和setter)内部使用

可以延迟初始化的方案: lateinit

主构造器

主构造器中不能包含任何代码,初始化代码可以放在初始化代码段中,初始话代码段使用init关键字作为前缀。
类体里面只能放声明语句,不能放执行语句

声明语句:属性的定义、函数(fun test())、内部类等 执行语句:println()、val x = 1 + 2、if判断等

为什么不把代码写在函数里,而是写在init里
写在函数里:只有调用该函数时才执行价
写在init里:创建对象时,代码自动执行

给个例子就能看懂了
image
运行结果是
image

  • 次构造函数
    次构造函数的constructor不能省略

  • 抽象类
    不能实例化
    可以有"空架子"方法:只允许声明方法名,不写具体实现(不给方法体{},要子类去重写
    kotlin默认类不可继承,必须加open在最前面

  • 嵌套类
    调用格式
    外部类.嵌套类.嵌套类方法/属性

  • 内部类
    使用inner关键字来表示
    内部类会带有一个对外部类的对象的引用,所以内部类可以访问外部类成员属性和成员函数

class Test {
    var v = "成员属性"

    fun setInterFace(test: TestInterFace) {
        test.test()
    }
}

/**
 * 定义接口
 */
interface TestInterFace {
    fun test()
}

fun main(args: Array<String>) {
    var test = Test()

    /**
     * 采用对象表达式来创建接口对象,即匿名内部类的实例。
     */
    test.setInterFace(object : TestInterFace {
        override fun test() {
            println("对象表达式创建匿名内部类的实例")
        }
    })
}

分析一下
整体分为三部分1. class Test 2. interface接口 3. main函数
接口是什么?为什么需要它?
接口就像一个合同或规范
它只是告诉你“你要做某件事”,但是不告诉你“具体怎么做”
任何类或对象只要实现了这个接口。,就必须提供test()的具体实现
为什么要用接口
因为Test类的setInterFace方法需要调用test()
setInterFace方法做了什么
它接收一个参数test,类型是TestInterFace(也就是接口)
然后调用了test()
在main里是如何调用的
先创建了一个Test的实例test
然后调用test.setInterFace(),括号里传入了一个对象表达式

  • 什么是对象表达式
    对象表达式是kotlin中创建内部匿名类的写法
    它的作用是::临时创建了一个实现接口的类的实例,而且这个类没有名字

整个执行流程

  1. main开始
  2. 创建Test对象
  3. 调用setInterFace, 并把一个匿名实现传进去
  4. setInterFace内部执行test.test(),此时调用的是我们刚刚传入的那个匿名对象的test()方法
    5.控制台打印

我不行了,这个kotlin我就先学到这里吧,我现在要去学习安卓开发了呀,时间差不多咯image

posted @ 2026-07-14 18:00  亜殦  阅读(5)  评论(0)    收藏  举报