非常喜欢Scala但是没法在工作中使用,该怎么办?

分享 未结
1 1 1 482
小编 2020-05-10发布
收藏 点赞
来源: https://www.zhihu.com/question/374554458/answer/1098699025

贴一个很不错的回复:

这道题反复在我的timeline上跳跃(骚动),我决定非常认真地以一个普通人/Scala忠实粉丝视角回答这个问题。

看到题主的标题,我仿佛看到了3年前的自己。时至今日仍忘不了刚接触Scala带来的冲击,这种感觉就像是《进击的巨人》中艾伦刚刚知晓墙外世界的存在一样。我清楚记得那时候废寝忘食地学习Scala相关知识,每天都会因为自己的点滴进步而开心。从接触Scala到现在我的心路历程大体上可以分为三个阶段:

膨胀期

刚对Scala基本语法有个大体了解的我,觉得之前写的都是些什么**。那时候最喜欢做的事情就是对比原来的冗长Java代码,用Scala写只需要几行就能搞定。以下是一些日常心里OS:

这什么垃圾,连pattern match都没有,写if else脑袋疼不疼 ;这什么垃圾,连值比较做不到,我Scala只需要一个 == 搞定;这什么垃圾,多值返回都不行,function(当让java的话应该叫method)参数都不支持默认值,一个方法写100遍累不累。这什么垃圾,函数一等公民都不支持,遑论匿名函数/lambda表达式/闭包支持了;这什么垃圾,写个懒加载这么多行,Scala一个lazy解决了;这什么垃圾,集合操作弱爆了;这泛型也配叫泛型,逆变协变都没有。

那个时候醉心于Scala的丰富特性和灵活性,对Java嗤之以鼻,甚至认为Scala无所不能。

迷惑失落期

随着对Scala更加深入的了解,我发现并不是很多人使用/喜爱Scala,对Scala的负面评价颇多,而且一些开源大项目开始开始移除Scala,而且不得不承认使用Scala的公司本身存量和增量都是不多的。我开始感到困惑和不解。

为什么Akka(Actor模型)在中国不温不火?​

这个问题正是处在迷惑失落期的我提的,那段时间我确实渐渐认清事实:Scala并不是一个主流/大众的东西。也有种深深的无力感,甚至想过如果自己暴富就给ScalaCenter捐一个亿(误)。

意志坚定期

如果不是真的喜欢,可能我在迷惑失落期就放弃Scala了。可我是真的喜欢Scala。首先认清现状,Scala确实不是主流,但是Scala在特定的分野是real king。而且Scala对于我来说,真是满足了我对编程语言绝大部分幻想,随着不断的学习思考和使用,我本身也慢慢形成了较为稳定的Scala风格,并且,一个很舒服的点是,理解了Scala的设计理念后,盲猜API并使用的感觉实在让人舒服。

工作上我用Scala参与或者负责的系统模块包括但不限于:

  • Unified SQL Query System
  • JSON Schema分析工具
  • 后端系统开发
  • 基于Akka的数据传输系统
  • 基于Akka的任务生命周期管理与调度系统
  • 公司内部的Flink SQL SDK

此外编写Spark/Flink任务,维护内部版本的Flink Table模块代码(比如说向planner中添加一个新算子和`OptRule`)势必要使用Scala,用Scala写DSL实在太香。还有我写脚本不用python用Scala(x

如何在工作中使用Scala

回到题主的问题,如果在工作中使用Scala。我和乐意把我的经验分享给题主。想在一个之前没使用过Scala团队使用Scala,我觉得得有以下几个先决条件:

  1. 团队人数<=5,就算是我这样一个Scala吹,也不觉得Scala,对于大多数业务团队来说,适合超多人协同工作(这点Java牛逼,别杠我Spark Kafka Akka啥的,那能一样吗)。
  2. 团队Leader至少要是对Scala不反对的态度,在这我要对我历任老板表示感谢,感谢你们的信任。
  3. 团队中至少有一个人愿意和你一起开拓Scala版图,独木难支,在这我也要对我历任同事们表示感谢,感谢你们愿意学习和尝试Scala,感谢你们
  4. 自己对Scala要熟识到一定程度,马丁老司机的《Scala编程》刷完我认为是必要的,也可以看看其他的Scala书,比如 @沈达
  5. @何品
  6. 翻译的《Scala实用指南》,友情提示,很多概念不要太过纠结,之后慢慢了解

以上这些先决条件达成后,我们来看看怎么慢慢引入Scala。我的核心思路就是一个词,那就是克制:

  • 克制地引入Scala Feature
  • 克制地使用Scala特性
  • 克制地选择模块使用Scala编写

解释一下上文的几个原则,Scala的特性可以说非常丰富了,但是特性的滥用往往是问题之源,也是造成大家对Scala难不好用的印象的最大原因。我个人的经验是,团队可以先约定只使用一部分Scala特性,先当better Java去写我认为完全没有问题。在团队引入Scala初期,我个人推荐使用的特性包括不限于模式匹配,多值返回,case class,val不可变对象,Option/Try, Scala collection,函数第一公民,Future/Promise(这个存疑)。Scala支持与Java的互操作,所以我建议先选新的模块使用Scala而不要去modify固有模块,还有就是可以在单元测试大量地使用Scala。

我来分享我个人工作中的一部分Scala Code Style:

我个人工作的Scala Code Style比较贴近于better Java,但是会比特性的使用上会相对丰富一点。

  • 我个人主张全局OO,局部借鉴FP的思想。我个人比较喜欢在描述一个Function工作流程的时候使用For Comprehension,逻辑很清楚,也会在validation的时候使用Applicative的思路。
  • 对于较长Function进行内部的拆解:
//这个function本质上要n步流程,需要的context需要含a,b,c,d
def foo(a:A,b:B,c:C,d:D):E = {
   //假设内部代码比较冗长
}

//将流程步骤拆解,这样再读代码时很清楚
def fooNew(a:A,b:B,c:C,d:D):E = {

@inline  def do1 = {//do 1}
@inline def do2 = {//do 2}
@inline def do3 = {//do 3}
 //....
 @inline  def doN:E = {}

  do1
  do2
  do3
//...
  doN 
}
  • 使用尾递归

我个人很喜欢使用尾递归,下面截图是一段脱敏的生产代码:

处理Binlog数据的Function

  • 谨慎地使用Implicit特性

怎么说呢,我个人对这个特性真是又爱又恨,在灵活性和代码优雅层面真是优秀,但是滥用肯定会带来问题,事实上我在生产代码上会用到这个特性,但是还是比较小心的,总体上也基本只是用implicit val 和 implicit class

  • scala.sys.process

这东西简直拯救了我,题主可以对比一下用Java写UnixProcess和Scala写scala.sys.process的巨大差距,太太太香了。

这篇回答算是我这个小透明在知乎回答最认真的答案了,其实码了多字的唯一动力无他,就是单纯对Scala的喜爱。我肯定没法像PL大佬从编程语言为你讲解那么多理论,也没法像工业界大佬打带给你那么多高屋建瓴的经验之谈。我能做的,就是站在一个普通人的视角把我的所见所感所想完完全全的分享给你。接触Scala后,我觉得我对编程语言的设计思路和做工程实践的经验都有着长足的提升和进步。

谈点感性的东西,我仍记得用Pure FP实现JSON Schema分析工具的那种成就感,寥寥几百行代码却极富于设计,逻辑相当自洽,真的是感觉自己 on the top of world。也记得耗尽了过年所有休息时间写的数据传输系统原型,回来跟老系统benckmark完全吊打老系统的自豪。Scala让我成就了用其他语言达不到的成就。记得高中时看钱钟书的《管锥编》,我印象很深的一句话就是:不了解所以不喜欢。现在Scala面临这个困局,很多人只听到传言就给Scala判了死刑,我想帮助大家正确地看待Scala,Scala确实有问题和缺点,但是同样也有很多闪光点。我也衷心希望看到我这篇答案的朋友可以不妨了解了解Scala,权当是茶余饭后的知识补充。大家有什么Scala问题欢迎交流,我会尽我所能解答,我搞不定也会去问问社区大佬们意见和建议的

利益相关:大三开始写Scala,整个程序员职业生涯(当然还不长)一直使用Scala/Java工作,并且业余写玩具100%都是Scala,并且,”我永远喜欢Scala“


回帖
  • 2020-05-13

    同样是大三开始写Scala,我已经开始怀疑下次还能不能找到Scala工作了

    0