技术经验谈 技术经验谈
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

hss01248

一号线程序员
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 最佳实践

    • Android数据库操作最佳实践
    • 基于蒲公英平台的app发布,更新,反馈功能的实现
    • testRss
  • ui

  • 优化

  • aop

  • apm

  • 架构

  • webview

  • rxjava

  • activity-fragment-view的回调和日志
  • Android加密相关
  • Android命令行操作
  • app后台任务
  • kotlin
  • kotlin漫谈
    • kotlin语言导论
    • sentry上传mapping.txt文件
    • so放于远程动态加载方案
    • states
    • Xposed模块开发
    • 一个关于manifest合并的猥琐操作
    • 玩坏android存储
    • 获取本app的安装来源信息
    • Android
    hss01248
    2021-04-02
    目录

    kotlin漫谈

    # kotlin漫谈

    具体使用入门/细节直接看官方文档,此文只谈对kotlin语言特性/语法糖的一些感受.

    一些语言特性可以结合编译生成的字节码来理解

    image-20210402094803485

    或者使用反编译为java的形式查看.

    image-20210402094956801

    image-20210402095137905

    # 扩展函数的本质

    调用时代码写法是对象.扩展(),实际编译成静态方法,被扩展对象本身(this)作为第一个参数传入.

    image-20210402100051345

    # 子类父类对象创建时初始化顺序

    没必要记,直接看字节码就行了

    // demo for init 
    open class DadConstructor(attr1: String){
    
        val firstProperty = "dad First property: $attr1".also(::println)
    
        init {
            println("dad init block 1")
        }
    
        val secondProperty = " dad Second property: $attr1".also(::println)
    
        init {
            println("dad  init block 2")
        }
    
        constructor() : this("erdai666"){
            println(" dad second constructor")
        }
    }
    
    class SonConstructor : DadConstructor{
    
        constructor() : super(){
            println("son second constructor")
        }
    
        init {
            println("son init block1")
        }
    }
    
    fun main() {
        SonConstructor()
    }
    
    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

    image-20210402101353008

    对应的方法:

    先父类init方法,然后子类init代码块,然后子类对应的构造函数.

    image-20210402101702105

    其最先调用父类的空init方法:

    image-20210402102330889

    从父类主init方法的字节码可以看出,一个对象初始化时,构造函数,变量,init块的初始化顺序:

    image-20210402102032554

    image-20210402102048159

    image-20210402102115659

    image-20210402102154160

    # 序列

    和python的yield关键字提供的生成器功能是一个道理.

    # 密封类 vs 枚举

    都是类型和有限个子类/对象都声明在同一个类/文件中

    密封类: 子类有限

    枚举: 对象有限. 只能是已声明的这些对象,且对象为单例.

    # 委托

    kotlin从语言层面提供委托代理的切面编程功能

    https://www.kotlincn.net/docs/reference/delegation.html

    • 委托类: 跟java的代理一样,只是在已知被代理类型时可以简化写法: 不需要更改的可以实现,维持原实现

    • 委托属性: 具有了类似js mvvm框架一样的对属性的切面功能,可以观测,拦截属性的变化.

      比如vue的计算属性:

      new Vue({
        data: {
          count: 10,
          blog:{
              title:'my-blog',
              categories:[]
          }
        },
        computed: {
          categories() {
            return this.blog.categories;
          }
        },
        watch: {
          categories(newVal, oldVal) {
            console.log(`new:${newVal}, old:${oldVal}`);
          }, 
        },
      })
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19

      在kotlin里使用委托属性来观察属性变化:

      class User {
          var name: String by Delegate.observable("<no name>"){
              prop , old , new -> 
              println("$old -> $new")
          }
      }
      
      fun main(args: Array<String>){
          val user = User()
          user.name = "first"
          user.name = "second"
      }
      
      //output:
      //<no name> -> first
      //first -> second
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
    编辑 (opens new window)
    上次更新: 2022/08/25, 20:20:31
    kotlin
    kotlin语言导论

    ← kotlin kotlin语言导论→

    最近更新
    01
    截图后的自动压缩工具
    12-27
    02
    图片视频文件根据exif批量重命名
    12-27
    03
    chatgpt图片识别描述功能
    02-20
    更多文章>
    Theme by Vdoing | Copyright © 2020-2025 | 粤ICP备20041795号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式