• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

卢晓春的博客

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

安卓笔记2——kotlin不写必忘的基本语法

说明

可能会忍不住说一些C#、Rust甚至Python相关的事情,但这是个人笔记,允许先入为主,节外生枝。
下文的最优写法只是相对于上下文环境

关键字、语法(糖)

一行代码省略函数体

有点像C#的 属性get函数写法的 =>

fun largerNumber(num1: Int, num2: Int): Int = max(num1, num2)

推导后可省略返回值类型

fun largerNumber(num1: Int, num2: Int) = max(num1, num2)

if可以将每个条件最后一行代码作为返回值

这有点像Rust

fun largerNumber(num1: Int, num2: Int): Int {
    return if(num1 > num2) {
        num1
    } else {
        num2
    }
}

相对最优写法

fun largerNumber(num1: Int, num2: Int): Int {
    return if(num1 > num2) {
        num1
    } else {
        num2
    }
}

when

也有点像Rust
匹配值 -> {执行逻辑}

when (num) {
    // 判断类型
    is Int ->   ...
    // 判断值
    1, 2 ->    ...
    in 1.. 10 ->    ...
    // 其它
    else -> ...
}

无参写法

when {
    name == "王旭林" -> 86
    name == "陈惠军" -> 77
    name == "黄达" -> 95
    name == "周毅" -> 100
    else -> 0
}

区间

val range1 = 0..10   // 包含0也包含10
val range2 = 0 until 10 // 包含0 但不包含10
val range3 = 10 downTo 1 // 包含10也包含1

for

for(i in 0 until 10 step2)  // 设置步长

面向对象部分

实例化

val p = Person()

open允许继承

open class Person{...}  // 该类可以被继承

class Student : Person {...}    // Student类继承Person类

主构造函数

感觉就是只能用来初始化一些字段(不考虑init块)

// 写法1
class Student(name: String){
    val name: String

    init{
        this.name = name
    }
}

// 写法2
class Student(val name: String){}   // 相当于直接定义了 val name: String 更简洁

次构造函数

就和Java里普通的构造函数一样的感觉,需要注意的是,通过次构造函数,必须直接或间接的调用主构造函数。
换句话说,主构造函数是必须执行的
使用constructor关键字

class Student(val sno: String){
    // 次构造函数
    constructor(sno1: String, sno2: String): this(sno1.plus(sno2)){}
}

接口

interface Study{
    // 抽象函数
    fun read(time: Int): Int
    // 也可以提供一个默认实现
    fun play () {
        println("play")
    }
    // 属性,注意不能初始化
    val prop: Int

    val propertyWithImplementation: String
        get() = "foo"
}

可见性修饰符

简直和C# 一模一样
public 和 private就是普通的意思
protected 仅子类可见
internal 仅同包下可见

data 数据类

暂时还没用过
自动实现 equals hashCode toString方法

data class Cellphone(val brand: String, val price: Double)

单例类

object Singleton{
    fun testFunc() {...}
}
// 调用
Singleton.testFunc()

静态方法(伴生类方式)

companion object

class BookKotlin {

    var name: String = "AA"

    fun speak() {}

    companion object instance {

        var nameStatic: String = "BB"

        fun speakStatic() {}

    }
}

注解,因为暂时用不到混合编程,略
自己写程序直接纯kotlin完事了。总轮不到我去维护老项目吧,安卓原生开发市场都那样了...

延迟初始化

允许为不可空类型不设置初始值,使用关键字lateinit

class MainActivity {
    private lateinit var adapter: MsgAdapter

    ...
}

集合创建

listof 创建列表

val list = listOf("xxx" ,"yy")  // 不可变列表,无法删除添加修改
val mlist = mutabeListOf("xxx", "yy")   // 可变列表

setOf 创建集合

同list,有setOf和mutableSetOf

mapOf 创建字典

val map = mapOf("xxx" to 1, "yy" to 2)
// 遍历
for((key, value) in map) {...}

集合的函数式API

对于搜索查询,有点像C#的Linq。总归好用的 舒服的
对于map filter,也像Python的类似函数(当然Linq的Select也有类似功能)
any all 更是一模一样

Lambda

基本结构

和C# 还是有点区别的
{参数名1: 类型, 参数名2:类型 -> 函数体}
函数体最后一行会自动作为表达式的返回值(相比Rust,没有分号作为区分)

简化写法

找最长单词

val list = ...
// 写法1 —— 最原始
val lambda = {word: String -> word.length}
val maxLength = list.maxBy(lambda)
// 写法2 —— 直接填入参数
val maxLength = list.maxBy({word: String -> word.length})
// 写法3 —— 如果lambda是最后一个参数,可以移动到括号外面
val maxLength = list.maxBy(){word: String -> word.length}
// 写法4 —— 如果lambda是唯一一个参数,可以省略括号
val maxLength = list.maxBy{word: String -> word.length}
// 写法5 —— 类型推导省略显式类型声明
val maxLength = list.maxBy{word -> word.length}
// 写法6 —— 如果lambda只有一个参数,可以用it替代,并省略 ->
val maxLength = list.maxBy{it.length}

// 省略参数
{ _, arg2, arg3 -> ...}
{ _, _ -> ...}  // 此时也没有it,并且不能省略_, _ -> 因为不是只有一个参数

可空类型

与Net8的可空类型有相似之处吧

类型定义

// 使用可空类型(加?)
fun doStudy(study: Study?) {...}

判空工具

  • ?.
a?.doSth()
// 等效为
if (a != null) a.doSth()
  • ?:
val c = a ?: b
// 等效为
val c = if (a != null) a else b
  • !!
    断言工具,认为肯定非空
  • let函数,避免反复?.
study?.let{
    it.readBooks()
    it.doHomework()
}

字符串格式化输出

"hello, ${obj.name}"
// 当表达式中仅有一个变量时,可以省略花括号
"hello, $name"

函数默认值可以不在最后几个函数

这比C#方便很多,明明C#也可以使用命名参数

posted on 2025-01-04 20:48  卢晓春  阅读(15)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3