转载

初见Kotlin

初见Kotlin

2016.03.16 16:27:01

初见Kotlin

前段日子 Kotlin 发布了1.0版,号称Android界的Swift,一副拯救苦逼Android码农于水火中的架势。那么它有何神奇之处呢?经过一段时间的摸索,Kotlin在我眼中定位为“通吃型”语言,服务端不是问题,还能生成JavaScript,另外又有针对Android开发的增强服务特性。

Kotlin一出世就被拿来跟Scala比较,恰巧Scala也是我喜欢的一门JVM语言。其实,我个人感觉 Kotlin并非Scala的小弟 ,只是说有了 valvar 的表象,给许多开发者这种感觉,但要这么说的话,Scala的函数/方法定义用 def 而Kotlin却用 fun 这又怎么说呢?此外,Kotlin的伴生对象跟Scala中的概念也区别不小。 另一种说法是Kotlin比Scala简单 ,也许Kotlin尚未实现Scala中我喜欢的 yield 功能,但要从发展角度来看,Kotlin出道时间短,后续要添加的功能应该会层出不穷。 Kotlin的用法并不简单 要说“骨子里”的像,我宁愿觉得Kotlin更像 Java

  • 号称“100% interoperable with Java™”:使用一段时间的感受是,写着写着,就有可能不知不觉中无缝地使用Java代码风格,写完了才恍然大悟......
  • 一方面Kotlin添加了大量函数式风格,它的map、filter等等操作比 Java 8 Stream的来得简洁直接。但隐约感受得到,这只是Kotlin特性中表面且很小的一部分, 涉及过多的功能需求时,还是要寻求Java的特性支持。这点不像Scala,Scala是能不用Java原生特性就不用,而Kotlin则是需要用时你用就是了。 不知道这是好事还是坏事,但终究看个人偏好吧,对于Java底子较好或较适应Java风格的开发者来说,这则是一个不错的起点。

上面是我觉得有必要澄清的一些概念。而 以下则是Kotlin吸引我研究下去的一些因素

  • Null Safety:别小看这一点,强迫症真能防范大量潜在问题。
  • Extension Functions:很喜欢这个特性,即开即用的感觉。
  • JetBrains家的东西,还是有些功底的,更重要的是跟闻名遐迩的自家开发工具必然结合紧密。
  • 充分考虑Android平台开发的环境及特性适配,也难怪称为“Android开发的Swift”。
  • 与Java的互操作性:也许会让大票开发者不感冒,但对我来说再好不过。

以下是Kotlin的一些限制,当然也只是我个人的一些看法:- 稳定性:尚待提高,特别是REPL工具,动不动就导致退出REPL环境。此外,代码中的空行及注释都会在REPL中引发异常。 - 文档:官方文档比较初级,且资源不多。 - 普及率:小众。TIOBE从上月起已经纳入了Kotlin的观察,首月排名貌似158位。

整个感受,用这个示例实现来解释最恰当不过了:

给一个自定义日期类添加 ComparisonRangeFor 迭代功能。

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语言的排名也不是很高。“该不该学”这个问题真没有答案。总之,它就是一门新兴的语言而已。

初见Kotlin

初见Kotlin

原文  http://www.2gua.info/post/53
正文到此结束
Loading...