Kotlin, Android的Swift
Kotlin, Android的Swift
苹果已经用Swift代替Objective-C,一种古老的语言,来进行iOS的开发了。明显Android开发也有这个趋势。
虽然现在已经可以选择Scala或者Groovy等基于JVM的语言开发Android应用来尝尝鲜,但是弊端却显而易见。
要引入一个全新的开发语言,那么就意味着需要引入这个语言的全部的运行时。这简直就是噩梦。因为这会给
极大的增加应用包的大小,还不说65535方法问题。小的应用还可以,但是这不是一个合适的替代语言应该有的问题。
Kotlin
介绍一下Kotlin--一个基于JVM的语言。由JetBrains(他们开发了IntelliJ IDEA的一个系列和Android Studio)
开发,并由圣彼得堡附近的一个小岛命名,负责这个项目的开发团队就在这个小岛办公。在2011年为外界
所致,并在几年后的第二个里程碑(M2)发布了对Android的支持(翻译的时候已经发布了1.0正式版)。
特性
这个新的语言有什么特色呢,你可能会问。有很多!不过本文会集中讲述Java应该有而一直没有的上面。
命名和可选参数
命名参数是一个很简单的语言特性,但是却让代码更加易读,尤其是那些有很多参数的函数签名。
看下面的例子:
void circle(int x, int y, int rad, int stroke) {
...
}
在java调用的时候看起来是这个样子的:
circle(15, 40, 20, 1);
要多次查看函数签名才能知道每个参数的具体作用。在Kotlin里,定义是这样的:
fun circle(x: Int, y: Int, rad: Int, stroke: Int) {
...
}
调用就更好了:
circle(15, 40, rad = 20, stroke = 1)
假设我们现在需要把stroke参数设定为可选的,在Java里你只能overload出另一个方法,这个方法
少一个参数,然后在里面调用第一个方法:
public void circle(int x, int y, int rad, int stroke) {
...
}
public void circle(int x, int y, int rad) {
circle(x, y, rad, 1);
}
但是在Kotlin里,一切变得简单:
fun circle(x: Int, y: Int, rad: Int, stroke: Int = 1) {
...
}
不是什么大的功能改进,但是Java始终没有。
Lambda表达式
最近函数式编程日渐流行。Kotlin也支持lambda表达式。
我们先来看一个简单的。假设你有一个整数列,而且要删除全部的奇数。
val numbers = listOf(1, 2, 3, 4, 5)
println(numbers.filter { it % 2 != 0 })
// 输出:[1, 3, 5]
这个函数把list的元素类型为输入参数类型,这里是integer。并输出一个boolean型的结果。如果我们把
filter的lambda表达式转化为一个明显的变量写出来的就更容易理解了:
val predicate: (Int) -> Boolean = { it -> it % 2 != 0 }
numbers.filter(predicate)
这一语法和其他的而支持lambda表达式的语言的语法相差不大,所以不多做解释。
Null和类型安全
总是要检查变量是否为null也是Java里一个很烦人的事。这个问题在Kotlin里被部分解决。
如果你用传统的方法定义一个变量,那么编译器是不允许其值为null的。
var text1: String = "something" // 木有问题
var text2: String = null // 无法编译
那么定义的变量的值需要为null怎么办呢?你要专门定义一个值可为null的变量。值可为null的变量,用变量
类型后面的问号来明确指定。
var text2: String? = null // 木有问题
调用的时候也需要问号。
text2?.replace(" ", "-")
这句的意思是:如果text2为空,那么replace()方法会被忽略并且不会有NullPointerException异常抛出。
如果你接手了一个可选类型(optional type)的变量,你可以百分之百的确认变量的值不会为null(这在Adnroid的API里
非常多见,虽然方法定义返回值为空可空类型,但是从来不会返回null),然后可以强制作为非空调用方法。
text2!!.replace(" ", "-")
这个时候,如果text2为null的话就会抛出NulPointerException异常。所以小心使用。
类型安全的另一个意义是类型检测。假设你又一个Context的实例并且需要检测这个实例是否为Activity类型,然后调用
一些activity才有的方法。
val context = getContext()
if (context is Activity) {
context.finish()
}
类型检测之后你就可以把context作为一个activity类型的实例来使用了,不需要强制类型转换。和Java的
instanceOf方法一样,is也是null安全的。即使getContext()返回一个null,上面的代码也
不会崩溃。
数据对象(Data object)
在写数据对象的时候,很多你需要手动实现的,比如:toString(), 'hashCode()以及equals()`。即使
现在很多的IDE已经减轻了一部分工作量,但是添加了新的成员后再更新这些实现也是非常的麻烦。
Kotlin里不用再为这些操心了。你需要做的只是在类定义的前面加一个data的修饰,上面的方法就已经隐式的生成了。
data class Island(val name: String? = null)
如果你初始化上面的类,会自动生成一个人类可以读懂的toString()方法。
val island = Island("Kotlin")
println(island.toString()) // 输出:Island(name=Kotlin)
同理,如果我们用同一个名字创建另外一个实例,这个实例会equal之前创建的实例。并且他们的hashCode()值也一样。
val island = Island("Kotlin")
val island2 = Island("Kotlin")
assert(island.equals(island2))
assert(island.hashCode() == island2.hashCode())
如果你要定制以上的方法,那么,当然,你还是要手写的。
单例
单例是一个非常常用的方法。Kotlin省去了创建单例的时候需要的静态getInstance()方法和私有的构造函数。
Kotlin使用object声明。
object ApiConfig {
val baseUrl: String = "https://github.com"
}
object声明也可以用来创建静态方法。
open class MyFragment : Fragment() {
companion object {
fun newInstance(): MyFragment = MyFragment()
}
}
上面的方法可以这样调用val fragment = MyFragment.newInstance(),就和Java的静态方法一样。
接口
虽然Kotlin不支持多继承, 但是还是支持接口的。只不过这个接口和Trait比较接近,可以在接口中包括默认实现。
interface SessionCloseable {
fun closeSession() {
Log.d(SessionCloseable::class.java.simpleName, "Closing...")
}
}
以上接口定义了一个可以关闭session的方法,下面我们在一个activity里实现这个方法。
class KotlinActivity : Activity(), SessionCloseable {
override fun onStop() {
super.onStop()
closeSession()
}
}
有一点需要注意的是Kotlin里没有extend和implement的区分,什么时候都是逗号分隔。
扩展(extension)
最后我们看一个例子:你可以给一个已经存在的类添加方法。
比如你要创建一个方法,这个方法可以把字符串的空白替换为下划线。在Java里你需要创建一个Utility的方法,以
原始字符串为参数。
public class StringUtils {
public static String encodeString(String str) {
return str.replaceAll(" ", "_");
}
}
在Kotlin里,你可以创建一个扩展方法(extension function),即使原类是final的。
fun String.encodeSpaces(): String {
return this.replace(" ", "_")
}
最后
为了公平起见,以上说到的大部分特性在Java8里都已经有了。但是这些什么时候可以在Android里用到可能
就遥遥无期了(其实这个问题已经有人在2014的Google I/O里问过了,但是根据Xavier Ducrohet的说法近期没有这样的计划)。
还好现在有Kotlin了。
另外,这个语言已经非常的成熟。唯一的问题就是文档经常补全而且还经常是过期的,不过因为语法和同时JVM语言的Scala多少
有些接近,多少可以猜出个大概。所以,这只是一个很小的瑕疵。
最后的最后,Kotlin将会在我(作者)后续的Android开发中尽可能的使用。显然,对已有的代码做转化不太明智。
而且Kotlin可以和Java的代码无缝互操作,这样不是什么太大的问题。Kotlin很值得一试!
Kotlin, Android的Swift的更多相关文章
- Kotlin & Android & Swift & Flutter & React Native
Kotlin & Android https://www.runoob.com/kotlin/kotlin-tutorial.html Swift 5 & iOS 12 https:/ ...
- Android与Swift iOS开发:语言与框架对比
Swift是现在Apple主推的语言,2014年新推出的语言,比Scala等“新”语言还要年轻10岁.2015年秋已经开源.目前在linux上可用,最近已经支持Android NDK:在树莓派上有Sw ...
- Kotlin Android学习入门
1.基本语法 https://github.com/mcxiaoke/kotlin-notes/blob/master/kotlin-tutorial-basic.md 2.推荐两篇Kotlin An ...
- Kotlin Android Extensions: 与 findViewById 说再见 (KAD 04) -- 更新版
作者:Antonio Leiva 时间:Aug 16, 2017 原文链接:https://antonioleiva.com/kotlin-android-extensions/ 在 Kotlin1. ...
- Kotlin Android Extensions (译文)
原文链接: http://kotlinlang.org/docs/tutorials/android-plugin.html Kotlin Android Extensions 本教程介绍如何使用Ko ...
- Kotlin Android项目静态检查工具的使用
Kotlin Android项目静态检查工具的使用 Kotlin Android项目可用的静态检查工具: Android官方的Lint, 第三方的ktlint和detekt. 静态检查工具 静态检查工 ...
- Kotlin Android Studio 环境搭建
Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源. Kotlin 可以编译成Java字节码,也可以编 ...
- [Android Pro] Swift 3.0多线程
本文只介绍Grand Central Dispath(GCD) 中央调度 个人认为一个GCD就够用了,可能是改版或是其他的在找之前写的多线程方法时发现不能用了,看文档之后发现改了,现在看上去更加简单易 ...
- 【转】Android世界的Swift - Kotlin语言
最近Oracle又在和Google撕的厉害,才知道还有这么Kotlin在Android像Swift在Mac的地位一说. Kotlin是一门与Swift类似的静态类型JVM语言,由JetBrains设计 ...
随机推荐
- Java运算符号,对象赋值,别名
生活发生的一切,才会促使着我继续前行,今天继续更新哦,看书中的代码练习. 例子1 引入net.mindview.util.Print.* ,方便打印结果. package com.date0529; ...
- JavaScript 练习题
练习题 1. 使用for循环输出1到50的值,要求每次循环只能输出一个值,每输出十个换一行. 2 日历生成器: 要求 用户输入,这个月有多少天,本月1号是星期几,自动生成日历 3. 表格生成器 4. ...
- DOM系列基础知识
DOM (Document Object Model) 即文档对象模型, 针对 HTML 和 XML 文档的 API (应用程序接口) .DOM 描绘了一个层次化的节点树,运行开发人员添加.移除和修改 ...
- 案例情景--在一次Oracle 数据库导出时 EXP-00008;ORA-00904:EXP-00000: oracle不同版本导入导出规则
案例情景--在一次Oracle 数据库导出时: C:\Documents and Settings\Administrator>exp lsxy/lsxy@lsxy_db file=E:\lsx ...
- Tech 2 doesn’t system for H2 above 2007
I purchased my Tech2 from obd2tool.com and it operates excellent. Can not definitely compare softwar ...
- 糟糕的@@identity,SCOPE_IDENTITY ,IDENT_CURRENT
在某数据库里面,某甲用@@identity来获取最近插入的id值,当在多人环境,发生获取到null值的问题. 那么@@identity是否有存在的必要? 感觉像生个孩子,多了个指头. 有的数据库的ge ...
- 无法将参数 1 从“WCHAR [256]”转换为“const char *”
https://blog.csdn.net/zhangxuechao_/article/details/81064037 字符集 修改为未设置 然后再修改回来unicode 居然好了
- cron Linux下的定时执行工具
说明:测试平台 Ubuntu 16.04.4 LTS cron是一个Linux下的定时执行工具,可以在无需人工干预的情况下运行作业.所以,在Linux中,周期性执行的任务一般由cron这个守护进程来 ...
- Python之路(第八篇)Python内置函数、zip()、max()、min()
一.python内置函数 abs() 求绝对值 例子 print(abs(-2)) all() 把序列中每一个元素做布尔运算,如果全部都是true,就返回true, 但是如果是空字符串.空列表也返回t ...
- redis在游戏服务器中的使用初探(三) 信息存储
摘要: 搭建了服务器环境 有了客户端 我们来假想下以下应用场景:我们简单举个实例来描述下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:用户ID,为查找的key,存储的value ...