初见Kotlin
2016.03.16 16:27:01
前段日子 Kotlin
发布了1.0版,号称Android界的Swift,一副拯救苦逼Android码农于水火中的架势。那么它有何神奇之处呢?经过一段时间的摸索,Kotlin在我眼中定位为“通吃型”语言,服务端不是问题,还能生成JavaScript,另外又有针对Android开发的增强服务特性。
Kotlin一出世就被拿来跟Scala比较,恰巧Scala也是我喜欢的一门JVM语言。其实,我个人感觉 Kotlin并非Scala的小弟 ,只是说有了 val
和 var
的表象,给许多开发者这种感觉,但要这么说的话,Scala的函数/方法定义用 def
而Kotlin却用 fun
这又怎么说呢?此外,Kotlin的伴生对象跟Scala中的概念也区别不小。 另一种说法是Kotlin比Scala简单 ,也许Kotlin尚未实现Scala中我喜欢的 yield
功能,但要从发展角度来看,Kotlin出道时间短,后续要添加的功能应该会层出不穷。 Kotlin的用法并不简单 。 要说“骨子里”的像,我宁愿觉得Kotlin更像 Java
:
Java 8
Stream的来得简洁直接。但隐约感受得到,这只是Kotlin特性中表面且很小的一部分, 涉及过多的功能需求时,还是要寻求Java的特性支持。这点不像Scala,Scala是能不用Java原生特性就不用,而Kotlin则是需要用时你用就是了。 不知道这是好事还是坏事,但终究看个人偏好吧,对于Java底子较好或较适应Java风格的开发者来说,这则是一个不错的起点。 上面是我觉得有必要澄清的一些概念。而 以下则是Kotlin吸引我研究下去的一些因素 :
以下是Kotlin的一些限制,当然也只是我个人的一些看法:- 稳定性:尚待提高,特别是REPL工具,动不动就导致退出REPL环境。此外,代码中的空行及注释都会在REPL中引发异常。 - 文档:官方文档比较初级,且资源不多。 - 普及率:小众。TIOBE从上月起已经纳入了Kotlin的观察,首月排名貌似158位。
给一个自定义日期类添加 Comparison
、 Range
及 For
迭代功能。
data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) : Comparable<MyDate> { override fun compareTo(other: MyDate): Int { val calendar1: java.util.Calendar = java.util.Calendar.getInstance() val calendar2: java.util.Calendar = java.util.Calendar.getInstance() calendar1.set(this.year, this.month - 1, this.dayOfMonth) calendar2.set(other.year, other.month - 1, other.dayOfMonth) return if (calendar1.before(calendar2)) -1 else if (calendar1.after(calendar2)) 1 else 0 } } class DateRange(val start: MyDate, val end: MyDate): Iterable<MyDate> { private var _dateRange: MutableList<MyDate> = mutableListOf<MyDate>() init { val calendar1: java.util.Calendar = java.util.Calendar.getInstance() val calendar2: java.util.Calendar = java.util.Calendar.getInstance() calendar1.set(start.year, start.month - 1, start.dayOfMonth) calendar2.set(end.year, end.month - 1, end.dayOfMonth) if (start < end) { _dateRange.add(MyDate(calendar1.get(java.util.Calendar.YEAR), calendar1.get(java.util.Calendar.MONTH) + 1, calendar1.get(java.util.Calendar.DAY_OF_MONTH))) val days = (calendar2.getTimeInMillis() - calendar1.getTimeInMillis()) / 1000 / 60 /60 /24 for (day in 1..days) { calendar1.add(java.util.Calendar.DAY_OF_MONTH, 1) _dateRange.add(MyDate(calendar1.get(java.util.Calendar.YEAR), calendar1.get(java.util.Calendar.MONTH) + 1, calendar1.get(java.util.Calendar.DAY_OF_MONTH))) } } } override operator fun iterator(): Iterator<MyDate> { return MyDateIterator() } inner class MyDateIterator: Iterator<MyDate> { private var _index: Int = 0 override operator fun hasNext(): Boolean { return _index != _dateRange.size } override operator fun next(): MyDate { return _dateRange[_index++]; } } } operator fun MyDate.rangeTo(other: MyDate): DateRange { return DateRange(this, other) }
>>> fun iterateOverDateRange(firstDate: MyDate, secondDate: MyDate, handler: (MyDate) -> Unit) { ... for (date in firstDate..secondDate) { ... handler(date) ... } ... } >>> iterateOverDateRange(MyDate(2016, 3, 10), MyDate(2016, 3, 14)) { println(it) } MyDate(year=2016, month=3, dayOfMonth=10) MyDate(year=2016, month=3, dayOfMonth=11) MyDate(year=2016, month=3, dayOfMonth=12) MyDate(year=2016, month=3, dayOfMonth=13) MyDate(year=2016, month=3, dayOfMonth=14) >>> iterateOverDateRange(MyDate(2016, 5, 1), MyDate(2016, 5, 5)) { println(it) } MyDate(year=2016, month=5, dayOfMonth=1) MyDate(year=2016, month=5, dayOfMonth=2) MyDate(year=2016, month=5, dayOfMonth=3) MyDate(year=2016, month=5, dayOfMonth=4) MyDate(year=2016, month=5, dayOfMonth=5) >>> iterateOverDateRange(MyDate(2016, 5, 1), MyDate(2016, 5, 1)) { println(it) } >>> (MyDate(2016, 3, 10)..MyDate(2016, 3, 14)).map { println("${it.year}-${it.month}-${it.dayOfMonth}") } 2016-3-10 2016-3-11 2016-3-12 2016-3-13 2016-3-14 [kotlin.Unit, kotlin.Unit, kotlin.Unit, kotlin.Unit, kotlin.Unit] >>> >>> fun checkInRange(date: MyDate, first: MyDate, last: MyDate): Boolean { ... return date in first..last ... } >>> checkInRange(MyDate(2016, 3, 13), MyDate(2016, 3, 10), MyDate(2016, 3, 14)) true >>> checkInRange(MyDate(2016, 3, 8), MyDate(2016, 3, 10), MyDate(2016, 3, 14)) false >>> checkInRange(MyDate(2015, 3, 13), MyDate(2016, 3, 10), MyDate(2016, 3, 14)) false >>>
刚好现在看到一个开发者的困惑:“ Kotlin让我感到不安。它离开Java 能玩得起吗 ? ”我觉得Kotlin发展的前提是不离开Java,这个前提没了,估计Scala、Clojure一样没戏—— Kotlin本身就是Java形态的增强与补充!
该不该学习Kotlin?——Kotlin就是一门语言,不是什么“十全大补丸”, 但其现在面临的最急迫任务就是普及与推广 ,至少要达到Groovy、Scala或Clojure等“同门师兄弟”的地位,虽然这些个JVM语言的排名也不是很高。“该不该学”这个问题真没有答案。总之,它就是一门新兴的语言而已。