转载自:https://www.jianshu.com/p/d527bd8e5472
这是一篇为公司内部”scala热情workshop”活动准备的文章,面向Scala初学者,目的在于帮助大家能尽早就建立起对Scala的整体认识,少走弯路。当然由于水平有限,有些地方可能不准确,不过如果能促进大家多思考多求证,也算达到了目的。
我最开始接触Scala到现在竟然已经过了4年半了。想到自己现在的scala水平,还处于入门后刚有点感觉的状态,感觉十分的惭愧。这四年多,一直断断续续的学习,中间多次放弃又多次拿起,就像是一本厚书,每次都是从头看了几十页便放下,多次之后,看到的还是前几十页。
我之前的学习完全是自学,靠自己摸索,在没有人指导的情况下,走了很多弯路。其中最大的阻碍,有两点:
自己在编程方面的知识储备不够,太多的东西需要现学,有时候甚至意识不到自己该学
对scala的定位和认识不清楚,常常在错误的方向上努力直到最后撞墙,而一些重要的知识却总在回避,导致学习过程特别的痛苦
所以我想把其中一些重要的东西记录下来,让和我一样正在学习scala的同学能多一些思考,少走一些弯路。
刚接触Scala的同学,看到的基本上都是一些宣传性的文章,也因此对它有一些不太正确的观点。
Scala很简单,Scala=Java+语法糖
在Scala群里,经常看到一些初学者在聊天的时候,说Scala不过是给Java增加了一些语法糖,让我们写代码的时候可以方便一些而已。他们很喜欢这些语法糖,因为写出来的代码看起来不像Java那么繁琐。在经过一两周的学习以后,他们认为自己已经掌握了Scala,觉得它很简单,于是跑到别的群里吹嘘,忽悠更多的人来学Scala。
的确,Scala中有一些东西看起来的确很简单,只需要把<<scala编程>>或者<<快学Scala>>这样的书大概翻过一遍,就差不多能用了。比如:
分号可选
多行字符串
val
object
trait
pattern matching
类型推断
map/filter/flatMap
for表达式
implicit
看起来,学习Scala就像爬楼梯一样,哪有什么学习曲线?
当我们基本掌握上面那些知识点之后,也许一些基本的Scala开发还能勉强胜任,但是我们很快就会发现很多别人写的Scala代码我们看不懂,别人讨论的Scala知识我们也看不懂,我们只是在把Scala当Java用。为什么?
因为那些真正让Scala具有吸引力、有难度的地方不在上面。比如:
类型系统
函数式编程
Monad
也许是因为那些书面向的都是初学者,在这些方面都讲得比较简略,点到即止。此时如果看<<Scala in Depth>>这本书,基本上很难看得下去。
当我们决定把这些都学会的时候,会惊讶的发现,难度变成了这样:
所以我通常会采用纯java或者纯scala方案,除非很有必要,并且两者可以分离得很清楚,并且之间只用很少的接口进行交互。
Java里有一些很好的库想在scala使用,人们通常都会先写一个wrapper,在外面包上一层scala接口。但是如果包的不好,用起来也是非常麻烦,不如不用,比如: http://scalafx.io
Java程序员学习Scala最容易
对于像我这样的Java程序员来说,函数式编程是一个很神秘的话题。从前以为,像Java/C这样的过程式语言的编程方式,就是全部,想不出除此之外还能有什么编程方式。所以对于“函数式”,我们往往通过一两个简单的定义会想像,然后得到“函数式编程”很简单的结论。
比如,关于函数式编程,有人说它有两个重要的特点:
追求不变性和无副作用
函数作为一等公民,它可以当作值一样定义、传递
然后我们想,我已经做到了尽量用val不用var,也不在方法里中做一些有副作用的操作,比如打印输出。然后,我还喜欢用那些好用的map之类的函数,直接写一个匿名函数给它,这不是符合了第二条吗?这样看来,函数式编程好像很简单啊。
这种想法,就跟我们会用class定义类了,然后就说自己会“面向对象”了一样。
由于我也刚刚开始学习函数式编程,没法给出准确的描述,只能大概说一些:在纯函数式编程中不能使用像 for
循环这样的语法,也不能给一个变量重新赋值,所以它解决问题的思路跟我们在过程式语言中做的,有很大不同。比如递归的大量使用,比如函数的组合,比如monad的概念,很多都是我之前从来没有见过的。在学习一门纯函数式语言的过程中,我们会发现以前的编程经验用不上了,经常有种寸步难行、有力无处使的感觉。而且会经常遇到各种数学相关的概念,还得不断补数学知识。
从一门过程式语言转向另一门过程式语言很快,可能要熟悉的就是语法、类库、一些最佳实践等,一两周可能就差不多了。但是从一门过程式语言转向一门函数式语言,可能要花几个月的时间。前者像是搬到了新城市,后者像是移民到了新国家。
(这一块要等我掌握了一门函数式语言之后再来补充)
Scala的DSL很强大
由于Scala强大的类型系统和它的语法支持,我们可以设计出强大的类型安全的DSL。
比如像scalatest这样的库,可以让我们这样写:
list should have length 3
这样看起来像是一句普通英语。
但Scala的DSL有两点需要注意:
它的特点是类型安全。如果以表达能力看,它比动态语言要弱要难看。可以通过查看sbt和gradle的构建文件来获取直观感受
对类型系统方面的能力要求高。以scalatest为例,如果没有熟悉、深刻地掌握scala类型系统,很难设计出来这样的DSL。而在动态语言中就没有这个门槛
所以个人感觉,scala中DSL的“强大”主要体现在类型方面,而在表达能力和易读性方面,可能要弱于其它一些语言。
类型系统我们不用学
Scala中的类型系统很强大,也很复杂,对于初学者来说是一个难点。记得以前看到有人说,普通的程序员?不需要掌握它们,只有类库的设计者需要掌握。
但是实际情况是,如果不能尽早的掌握足够的类型系统知识,在使用Scala时我们几乎寸步难行。我们在编译Scala代码时,遇到的最多错误就是各种类型不匹配,如果不熟悉的话,可能要卡几个小时都解决不了。
所以在最开始学习的时候,就不能回避它。也许我们的目的不是设计出一个类型很复杂的类库,我们也要能做到看得懂复杂一点的方法签名,解决常见的类型编译错误。
我公司有个新项目,我想用Scala,边学边用
很多人低估了Scala的学习难度,甚至刚开始学习时,便打算在公司的新项目上使用。或者在自己也没有熟练掌握的情况下,便向团队中强推Scala,这种做法是十分危险的。
Scala中关于函数式与类型系统方面的知识,对团队成员的要求比较高。如果是一个在这些方面不熟悉的团队,想在短期内掌握并且用好它们,基本上是一件不可能的任务。
另外,Scala的IDE支持、资料文档、生态圈等,相对于Java这种成熟的语言还比较弱,这对于新人也是一个比较大的障碍。
我觉得,只有当团队中已经有对Scala熟练的人,团队成员学习能力较强,并预留了大量学习时间的情况下,才可以尝试使用Scala来做项目。
有不少人问过我这个问题:你为什么要学习Scala?
在最开始,我也是被各种宣传忽悠了,以为Scala是一门简单的,对Java有很多改进的,甚至可能很快就成为下一代Java的语言。当时正打算做一个网站,于是就用它边学边做。几个月后,实在无法忍受它的编译速度、各种类库的缺失、以及各种各样的编译错误,放弃了它。
但是当时创建的那个Scala群里,却有非常好的交流氛围。很多人由于对Scala很有兴趣,在群里讨论各种新鲜好玩的技术,让我大开眼界,发现Java原来只是一个小世界。另外在群里认识了杨云,也因此加入了TW,现在他是我的sponsor。
来到我们公司之后,居然有两次参与Scala项目的机会。发现我们的客户居然都喜欢用Scala,西安办公室里也有越来越多的人主动或者被迫学习Scala。由于现在有了更多学习的时间,所以我又把它捡了起来,同时惊喜地发现之前一直没搞懂的问题,现在竟然差不多理解了。
我认为我现在学习Scala的原因是:它为我打开了编程世界的一扇门,让我看到了与之前完全不同的世界。通过对它的学习,我可以强迫自己学习更多编程知识,提高自己的能力,从而有机会跟更多牛人交流。另外,我个人也看好Scala的未来,所以认为越早掌握它对自己越有利。
Scala学习路线
结合我自己的学习经历,我把Scala的学习按难度分成了几块。每一块的难度侧重点相对独立,需要一段时间的专门学习。
第一块:语法糖
第一块是学习Scala的各种基本特性,比如object, trait, pattern matching等,这些知识对于一个熟练的Java程序员来说,没有太大难度。看完一本Scala书,或者参与一个不太复杂的Scala项目,基本上就可以到达。
推荐书籍: << Scala编程>> 或者 <<快学Scala>>
文章:Daily Scala: http://daily-scala.blogspot.com/
开源项目: https://github.com/inca/circumflex/tree/master/web
Circum-web是一个比较简单的scala mvc框架,代码简单、注释丰富。由于它没有用到多少函数式风格的代码,对于初学者来说,还是比较容易上手的。虽然现在用它的人不多,但不失为一个很好的学习资源。同时它还有circum-orm等项目,也可以用来学习。
第二块:类型系统
此时最困扰我们的,应该就是各种各样类型相关的编译错误,以及一些复杂难懂的类型声明。
特别是这几个方面:
路径依赖类型
非变,协变,逆变
Type class
高阶类型等
推荐书籍: <<Scala in Depth>>
博客文章:
http://hongjiang.info/scala/ 中有关类型系统的文章
http://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/
参考语言:Haskell中的类型系统
第三块:函数式
这一块的目标就是搞懂monad,以及各种函数式编程中提到的概念。这里可能要结合其它函数式语言学习。
推荐书籍: <<Scala in Depth>>
<<functional programming in scala>>
推荐博客:
http://hongjiang.info/scala/ 中关于monad的文章
Manods are elephants系列: http://james-iry.blogspot.com/2007/09/monads-are-elephants-part-1.html
论面向组合子程序设计方法: http://www.blogjava.net/ajoo/category/6968.html
Learning scalaz: http://eed3si9n.com/learning-scalaz/
推荐库:scalaz
推荐语言:Haskell
第四块:生态
前三块基本上都是语言层面,这一块是库,比如一些我们经常用到的,或者scala中一些很有名的库:
构建工具: sbt
scalatest/specs2
scalaz
akka
spark
这里要根据项目和兴趣进行选择。
第五块:其它
Scala中的一些其它特性,比如:
Dynamic: http://stackoverflow.com/questions/15799811/how-does-type-dynamic-work-and-how-to-use-it
macro
scala.js, jsscala
原文:https://www.cnblogs.com/doubleyuan/p/9272934.html