前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kotlin-Android的另一番风味

Kotlin-Android的另一番风味

作者头像
微信终端开发团队
发布2018-11-02 15:52:45
10K0
发布2018-11-02 15:52:45
举报

微信 订阅号助手 的Android App项目首次尝试使用Kotlin进行大规模的业务开发(483个Kt文件,3.8W行不包含空行的Kt代码),一开始接触Kotlin的时候难免会有点不适应,但经过几天的强制使用后,慢慢有些感觉,项目落地后回顾了一下,发现Kotlin确实是有它独特的风味

烹饪准备

  • 食材
    • Android,主要食材(指Framework、Api等),
    • Kotlin,食用安全、味鲜(扩展函数)、香(重载)、甜(富含糖份Lambda),第二主要食材,切好块状
    • Java,少量,Kotlin这种食材需要它来做引子
  • 锅,AndroidStudio、Eclipse这两个牌子的锅质量都不错
  • 调味料,Kotlin Android Extension、Android KTX、AndroidX、Anko等
  • 如果没有上述这些材料请移步到如下网址"购买"
    • https://developers.google.com/android
    • https://kotlinlang.org/docs/reference
    • https://www.oracle.com/java

烹饪过程

  • 开火,放少量食用油
  • 先把Android倒进去,伴两下
  • 倒少量Java,主要是"字节码"和"工具部分",再伴两下
  • 把切好块的Kotlin一块块慢慢平铺在Android上面,把Android盖住
  • 慢火煮3-5分钟,观察一下这个过程
    • Kotlin把Android的味道慢慢释放出来,比Android + Java更香
    • Kotlin与Java融为一体 (前提是少量Java,如果Java放得太多,香味会受影响,粘合不够好,容易松散(NPE))
  • 关火,焖一会

开锅,上菜

色香味倶全,敬请尽情享受这番独特的风味

特色风味一,食用安全

食用安全,Nullable or NotNul从源头抓起,Kotlin代码安全性更强

代码语言:javascript
复制
var output: String
output = null   // Compilation error

val name: String? = null    // Nullable type
println(name.length())      // Compilation error

食用安全从从源头上抓起,只要跟定义不符就编译不通过,这是Kotlin小而精的一个优点,一下子能把整碟"菜"的安全系数提高,此Code来自官方文档

特色风味二,鲜

扩展函数,味道鲜美,百吃不厌

项目工具类的另一种写法

代码语言:javascript
复制
fun String.toIntSafely(defaultValue: Int = 0): Int {
    return try {
        this.toInt()
    } catch (e: Exception) {
        defaultValue
    }
}

fun main(args: Array<String>) {
    println("1".toIntSafely())
}

String 转 Int,这种需求几乎很多项目都是需要,像上述Kotlin如果是在Java里面描述的话,估计会写成这样

代码语言:javascript
复制
public final class StringUtil{
    private StringUtil() {}
    public static int stringToInt(String string, int defaultValue) {
        //省略
    }
}

使用时

StringUtil.stringToInt("1", 0);

大家看到这里可能会觉得没什么,大家都是工具类,用的时候有些小差别而已

但正因为这些小差别,优点就体现出来了,确实是鲜美

  • 不需要记住工具类的名字和方法的名字,假如你是一个刚接手项目的新人,正准备做一个需求开发,突然需要这种String to Int的工具,但是不知道工具在哪,这就好比你去到一个陌生人的家里,想找个螺丝刀拧个松掉的螺丝一样,这“螺丝刀”在哪?除了问“主人”之外,要么就是“翻柜子”,这不就显得效率低么?使用Kotlin的扩展函数就能有效避免前面所说的问题,接手项目的新人只需要轻轻的“.”一下,滚两下鼠标,"toIntSafely"的方法就会看到。这就为什么你看Kotlin的Java扩展库很多都是通过扩展函数来封装
  • 方法的类归属更好理解,以上述的"toIntSafely"为例,String.toIntSafely,使得开发者更容易直观感受到这个函数是用于String,不像StringUtil.stringToInt没有归属可言,纯粹就是一个工具函数,不如Kotlin的写法容易理解
  • 对定义函数者的要求高了,正因体现了函数的类归属,也就使得开发者在定义函数的时候需要考虑归属给哪个类还是顶层函数这些问题,归属的范围少了,会导致不好用,范围广了又怕暴露导致滥用或者误用

特色风味三,香

重载(Overload),回味无穷

虽然这个概念在面向对象领域用得很多,但Kotlin这个重载的味道真是令我们吃上瘾

重载在工具类的场景用得非常多,一个项目下来没工具类也是不可能,例如我们在项目中会封装一些对话框(Dialog)工具类供开发的同学一句调用

  • 开发的同学需要在界面显示一个Dialog,只想改变Dialog的内容,那么Java里面就有showDialog(String message)的写法
  • 开发的同学需要在界面显示一个Dialog,即想改变Dialog的标题,又想改变Dialog的内容,那么Java里面就有showDialog(String title, String message)的写法
  • 开发的同学想改变Dialog里面Icon的....
  • 开发的同学想......

这些场景估计做Android开发的同学都会碰到,其实不限于Android,Java开发的同学也经常遇到,我们看看Kotlin是怎样把这些需求收拢

代码语言:javascript
复制
fun showDialog(title: String = "标题", message: String = "内容") {
    //TODO
}

这个写法一下子满足 2的2次方(4) 种重载方法

代码语言:javascript
复制
showDialog()

showDialog("新标题")

showDialog(message = "新内容")

showDialog("新标题", "新内容")

这种重载方式有效地减少我们项目中的重载方法数量,使得我们项目开发更简洁和更有效率 ,自然就回味无穷

特色风味四,甜而不腻

带了糖,甜而不腻

Kotlin里面Function与Lambda既可相互理解,又有其味道(写法)上的一些差异

味道 (结果) 一样,但味道消去的过程 (用法) 有差别

Function(函数)常用写法

代码语言:javascript
复制
fun f(x: Int): Any {
    return Any()
}

用法

代码语言:javascript
复制
val y = f(1)    

Function(函数)的一种Lambda写法

代码语言:javascript
复制
fun f() = { x: Int -> Any() } 等价于 fun f(): (Int) -> Any = { x: Int -> Any() }

用法

代码语言:javascript
复制
val y = f()(1) 或 val y = f().invoke(1)

Lambda写法

代码语言:javascript
复制
val f = { x: Int -> Any() } 等价于 val f: (Int) -> Any = { x: Int -> Any }

用法

代码语言:javascript
复制
val y = f(1) 或 val y = f.invoke(1)

细节点:Function时,有"="跟没有"="意义不一样,有"="的时候可以理解右边( { x: Int -> Any() } )是 左边函数返回类型((Int) -> Any) 的实现

函数不用置疑,项目里面必备

Lambda

Lambda,语法糖,这是怎样的一种成份?

Lambda是长这样的

代码语言:javascript
复制
val block: () -> Unit = {}
val sum: (Int, Int) -> Int = { p1, p2 -> p1 + p2 }

Lambda令我们的项目减少了很多接口类,尤其是回调接口,我们项目几乎没有。一般的业务场景里面回调接口都会用得不少,Lambda能有效减少这种Callback接口的定义,少写不少接口类,事半功倍。

另lambda里面不能写return,最后一行的值就是返回值

从数学函数角度抽象理解

代码语言:javascript
复制
函数: y = f(x)

假设x与y都是Int类型

可以理解为 Kotlin 函数:

代码语言:javascript
复制
fun f(x: Int): Int {
    return 1 // 这里的返回值就是对应y
}

也可以理解为 Lambda:

代码语言:javascript
复制
val f = { x: Int -> 1 } 等价于 val f: (Int) -> Int = { x: Int -> 1 }

使用时f(1),但是如果像上述那种f(x)的kotlin函数与f(x)的lambda同时同名同方法签名存在,使用上要f(1)与f.invoke(1)来区分是函数调用还是lambda调用

假设x与y都是Lambda类型

x是Lambda类型 (Int) -> Int ,y是Lambda类型 (Int) -> Int,可以换算成

代码语言:javascript
复制
fun f(x: (Int) -> Int): (Int) -> Int {
    return { it -> x(it) }
}

或这样

代码语言:javascript
复制
fun f(x: (Int) -> Int): (Int) -> Int = { it -> x(it) }

使用时

代码语言:javascript
复制
f { it -> it + 10 }(1) or f { it -> it + 10 }.invoke(1)

或 Lambda

代码语言:javascript
复制
val f: ((Int) -> Int) -> ((Int) -> Int) = { x -> { it -> x(it) } } // val时要inline

使用时

代码语言:javascript
复制
f.invoke { it -> it + 10 }.invoke(1)

通过上述的 替换 能更好地理解和使用Lambda

如何更好地了解Kotlin这种食材的味道

  • Kotlin用于Java领域,中间产物毫无疑问还是字节码,因此本质还是Java的基础知识,反编译Kotlin生成的字节码是学习Kotlin一种较好的方式,可利用AndroidStudio的Tools来反编译kt,能帮助快速理解Kotlin

谢谢品尝这份美味

希望Kotlin这款食材能带给各位读者不少Android上的特色的风味

参考食谱

代码语言:javascript
复制
https://kotlinlang.org
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WeMobileDev 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 烹饪准备
  • 烹饪过程
  • 开锅,上菜
  • 特色风味一,食用安全
  • 特色风味二,鲜
    • 扩展函数,味道鲜美,百吃不厌
    • 特色风味三,香
      • 重载(Overload),回味无穷
      • 特色风味四,甜而不腻
        • 带了糖,甜而不腻
          • 味道 (结果) 一样,但味道消去的过程 (用法) 有差别
            • Lambda
            • 如何更好地了解Kotlin这种食材的味道
            • 谢谢品尝这份美味
            • 参考食谱
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档