学习Scala: 初学者应该了解的知识
[comment]: # 学习Scala: 初学者应该了解的知识
Scala开发参照清单
这里列出在开发一个Scala工程中需要参照的资料。
官网网站
文档网站
http://docs.scala-lang.org/index.html
Cheatsheet
http://docs.scala-lang.org/cheatsheets/
代码风格
http://docs.scala-lang.org/style/
设计模式
https://wiki.scala-lang.org/display/SYGN/Design+Patterns
Language Specification
http://www.scala-lang.org/files/archive/spec/2.11/
API
http://www.scala-lang.org/api/current/#package
Scala wiki
Scala Tools and Libraries
https://wiki.scala-lang.org/display/SW/Tools+and+Libraries
Scala的初次约
Scala是由Martin Odersky设计的一种结合了函数式编程(不仅仅有这个)的强类型语言。
Scala的代码会被编译成Java bytecode,并在JVM上运行的。
可以认为Scala是Java的扩充,一个Java语言的超集。
Scala的设计思想之一,来自于对Java语言的一些缺点的批评。
个人也觉得Java语言发展的太慢,尤其是和C#、.NET相比。
Scala的横空出世,提供了一个积极性的灵感,解决了Java语言的发展问题,给Java社区带来强大的活力。
Scala的优势
Java有的优势,Scala都有
Scala的编程风格更简洁
Scala的简洁风格,也很可能降低可读性。所以在团队开发中,还是需要一个良好的代码规范来约束。
- 性能很好
和Java的性能一样,比Python快的太多了。 - 可以直接使用Java类库。
 - Java也可以使用Scala的类库。
个别情况下,需要在Scala里做特殊的支持。 
Scala的用途
结合Spark,处理大数据。
这是,目前,Scala的一个主要应用。Spark也是那Scala写的。Java的脚本语言版
可以直接写Scala的脚本,也可以在.sh直接使用Scala。代替Java。
scala希望提供一种简洁的语言。不过作为初学者的我,scala极其容易导致代码的可读性比较差。
Java语言还是有其优势。
Scala的代码风格
由于Scala结合了函数式编程和面向对象语言特征,从这个方面看,有两种编程风格可以选用。
- 支持函数式编程的面向对象编程风格
 - 函数式编程风格
 
如果你开发的项目主要用于处理数据,函数式编程风格更适用。
本文也主要针对函数式编程风格。
安装scala
可以从scala的官方网站上下载。
许多人会选择Intellij IDEA或者Eclipse作为scala的编辑器。
这里有个使用Visual Studio Code作为编辑器的介绍:
Scala on Visual Studio Code
函数式编程到底意味着什么
Scala的再认识
trait, class,object
开始学习Scala会看到trait这个奇怪的词,而且可以def object。这里解释一下:
trait:   类似于Interface,不过可以实现声明的方法。
class:    就是class.
object:   就是Module,一个静态类。
Scala的语言特征
除了Java的语言特征外,Scala还提供了一下主要特征。
(这个章节比较深奥,可能不足,需要慢慢地更新)
函数式编程(functional programming)
上面已经说过了。
类型推测(typing inference)
这个特征C#也有。建议大家尽量使用这个特点。也就是说
- 避免定义变量的数据类型
一个好处是类型发生变化的时候,改动的代码会相对较少。 - 对于函数,要定义输入和输出的数据类型。
 
implicit特性
我把对implicit的认识分为这几个Levels。
Level 0: 完全忽略implicit的存在
如果,你在你的项目里发现有人使用implicit,可以理直气壮地批评,这是降低可读性的杰作。
implicit特性应该避免被使用。implicit很可能给读代码的人带来困惑,属于反直觉的代码。
Level 1:简单的认识implicit conversions
比如:一个函数的参数的Long型,调用时输入一个Int型的数据,也不会出错,
其后面就是implicit conversions功劳。
implicit conversions逻辑发现类型Int/Long不匹配,
然后在一个implicit view(可以看成一个函数pool,包含了所有的implicit functions)中找一个输入为Int,输出为Long的函数,
最后通过这个函数完成类型的转换。
Scala自身提供了一些必要的implcite conversion functions.
Level 2: 对implicit的有个基本理解
implicit的使用
使用起来很简单,直接把implicit关键字,加到trait/class/object/def/val之前就可以。
在Scala 2.10版后, implicit可以用在三个地方:
例如:
- implicit functions vs implicit conversions
 
implicit def int2ordered(x: Int): Ordered[Int] =
  new Ordered[Int] { /* .. */ }
- implicit classes
implicit classes是针对Pimp-my-library pattern,在Scala语法上的实现。
这个和C#的extesion methods的用意是一样的。
比如,你想在Scala的List类上,增加一个函数,而不用去修改Scala的发布包,
在Scala 2.10版以后,就可以通过implicit classes实现,
之前的版本,可以通过Pimp-my-library pattern实现。
在下面这个例子中,如果import Helpers._,类IntWithTimes的所有方法都会作用于Int上。 
object Helpers {
  implicit class IntWithTimes(x: Int) {
    def times[A](f: => A): Unit = {
      def loop(current: Int): Unit =
        if(current > 0) {
          f
          loop(current - 1)
        }
      loop(x)
    }
  }
}
- implicit values vs implicit parameters
来自官方的一个例子: 
object ImplicitTest extends App {
  /**
   *  To show how implicit parameters work,
   *  we first define monoids for strings and integers.
   *  The implicit keyword indicates that the corresponding object can be used
   *  implicitly, within this scope, as a parameter of a function marked implicit.
   */
  implicit object StringMonoid extends Monoid[String] {
    def add(x: String, y: String): String = x concat y
    def unit: String = ""
  }
  implicit object IntMonoid extends Monoid[Int] {
    def add(x: Int, y: Int): Int = x + y
    def unit: Int = 0
  }
  /**
   *  This method takes a List[A] returns an A which represent the combined
   *  value of applying the monoid operation successively across the whole list.
   *  Making the parameter m implicit here means we only have to provide
   *  the xs parameter at the call site, since if we have a List[A]
   *  we know what type A actually is and therefore what type Monoid[A] is needed.
   *  We can then implicitly find whichever val or object in the current scope
   *  also has that type and use that without needing to specify it explicitly.
   */
  def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
    if (xs.isEmpty) m.unit
    else m.add(xs.head, sum(xs.tail))
  /**
   *  Here we call sum twice, with only one parameter each time.
   *  Since the second parameter of sum, m, is implicit its value is looked up
   *  in the current scope, based on the type of monoid required in each case,
   *  meaning both expressions can be fully evaluated.
   */
  println(sum(List(1, 2, 3)))          // uses IntMonoid implicitly
  println(sum(List("a", "b", "c")))    // uses StringMonoid implicitly
}
implicit的功能可以分为两类:
implicit conversions (from implicit functions and implicit classes)
当Scala发现类型不匹配,或者正在调用一个对象不存在的函数时,
Scala compiler就会去implicit function list中找一个匹配的函数。implicit arguments (from implicit values and implicit objects)
在函数上可以定义一个implcit参数,编译器会在implicit的对象列表中,
找到一个类型匹配的对象,并传入。
作用域
可以想到,implicit有个作用域。这个作用域,和当前的package,以及import的类,
还有Scala的默认有关。
Level 3: 重申:避免使用implicit
Level 4: 如果要使用implicit
- 好好阅读关于implicit作用域,编译器的查找complicit对象的顺序等知识。
 - 定义implicit的开发规范
 - 写好文档帮助开发人员和用户理解。
 - 限制其使用的场景
- 你要实现一个类似于虚数这样的新数据类型。
 - ...
 
 
Collection
Mutability vs Immutability
可变的变量(Mutable variables)(主要是可变的对象)会引起一些潜在的问题:
- 变化后,可能在map中找不到了
 - 性能损失(在多线程下,读写需要加锁)
 
编程方面的建议是:
- 如果可能,使用和开发 immutable 类。
 
杂七杂八
_ 的用途
Null, null, Nil, Nothing, None, and Unit
Null是Scala中的一个Trait.
null是一个Null的实例,相当于Java中的null。在面向函数编程中,不要使用,用None代替。
None是一个None.type的实例,代替null。
在一个函数中,用于表达这个函数返回了没有值。可以避免 null pointer exception。Unit是Scala中的一个类型,用于表示一个函数没有返回值。
有点像Java中的void,不过其实返回了'()'。
  // There is no '=' before '{', so the function return Unit.
  def funUnit(x: Int) {
    x * x
  }
  // There is a '=' before '{',
  // so the function returns the value of the last expression.
  def funReturnLastStatement(x: Int) = {
    x * x
    x + x
  }
  // Recommend to use explicit return type, and = forever.
  def funReturnLastStatementGood(x: Int) : Int = {
    x * x
    x + x
  }
- Nil 是一个空的List实例.
 - Nothing是Scala中的一个Trait。基本上没有用。(我猜的)
 
## 和 == 对 equals 和 hashCode
在Scala中, ##方法相当于Java中的hashCode方法。
方法相当于Java中的equals方法。
建议使用##和,因为Scala针对value类型实现额外的功能。
Generic classes/functions: +T, -T, <:, >:, <&
- +T: 作用于class, 用于协变(covariant)
 - -T:作用于class, 用于逆变(contravariant)
 
+T, -T 作用于泛型对象之间赋值。
- T <: A: 作用于 function, 约束:T是A的子类,也称作upper type bound,这是一个协变。
一般会和-T合用。 - T >: A: 作用于 function, 约束:T是A的超类,也称作lower type bound,这是一个逆变。
一般会和+T合用。 - T <& A: 作用于 function, 约束:存在一个T => A的implicit conversion,也称作view bound.
 
<:, >:, <& 作用于泛型函数之间赋值。
请看不变(Invariant), 协变(Covarinat), 逆变(Contravariant) : 一个程序猿进化的故事
编译.scala文件到jar文件
scalac -d test.jar D:\project\*
参照
- Scala in Depth by ScalaJoshua D. Suereth
 - Community-driven documentation for Scala
 - Scala design patterns
 - Scala guide and cheatsheet
 - Scala (programming language)
 - Lambda calculus
 - Null, null, Nil, Nothing, None, and Unit in Scala
 
学习Scala: 初学者应该了解的知识的更多相关文章
- 如何快速学习Scala
		
大数据学习过程中,会学习非常多的技术,但SCALA无疑是必不可少,那我们在大数据技术的学习过程中,如何快速的认识scala,并且学习它,感谢科多大数据公司的余老师提供的详细素材,本人整理成章,希望对你 ...
 - 学习	shell脚本之前的基础知识
		
转载自:http://www.92csz.com/study/linux/12.htm 学习 shell脚本之前的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写sh ...
 - 学习Scala第一篇-从hello World开始
		
最近开始系统性的学习scala.其实之前使用过scala的,比如我在用Gatling这款性能测试工具的时候就接触到了scala了.Gatling本身就是用Scala写的,而且Gatling的性能测试配 ...
 - 怎样学习Scala泛函编程
		
确切来说应该是我打算怎么去学习Scala泛函编程.在网上找不到系统化完整的Scala泛函编程学习资料,只好把能找到的一些书籍.博客.演讲稿.论坛问答.技术说明等组织一下,希望能达到学习目的.关于Sca ...
 - HTML+CSS学习笔记 (7) - CSS样式基本知识
		
HTML+CSS学习笔记 (7) - CSS样式基本知识 内联式css样式,直接写在现有的HTML标签中 CSS样式可以写在哪些地方呢?从CSS 样式代码插入的形式来看基本可以分为以下3种:内联式.嵌 ...
 - 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句
		
salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...
 - 刚开始学习Javascript的一些基础小知识,从入门到崩溃,希望对大家有帮助(只适合初学者)
		
一.简介 1.JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型,js不能操作文件. 重要的开始啦!!!!! 引入javascript: 行间js <d ...
 - Python学习系列(二)(基础知识)
		
Python基础语法 Python学习系列(一)(基础入门) 对于任何一门语言的学习,学语法是最枯燥无味的,但又不得不学,基础概念较繁琐,本文将不多涉及概念解释,用例子进行相关解析,适当与C语言对比, ...
 - 大数据学习day23-----spark06--------1. Spark执行流程(知识补充:RDD的依赖关系)2. Repartition和coalesce算子的区别 3.触发多次actions时,速度不一样 4. RDD的深入理解(错误例子,RDD数据是如何获取的)5 购物的相关计算
		
1. Spark执行流程 知识补充:RDD的依赖关系 RDD的依赖关系分为两类:窄依赖(Narrow Dependency)和宽依赖(Shuffle Dependency) (1)窄依赖 窄依赖指的是 ...
 
随机推荐
- aspose.cell 设置excel里面的文字是超链接
			
目的: 1.通过方法designer.Workbook.Worksheets[0].Hyperlinks.Add("A1", 1, 1, url);给导出到excel里面的数据加上 ...
 - CSS技巧(二):CSS hack
			
什么是CSS hack CSS hack由于不同的浏览器,比如IE6,IE7,Firefox等,对CSS的解析认识不一样,因此会导致生成的页面效果不一样,得不到我们所需要的页面效果. 这个时候我们就需 ...
 - Qt编写自定义控件二动画按钮
			
现在的web发展越来越快,很多流行的布局样式,都是从web开始的,写惯了Qt widgets 项目,很多时候想改进一下现有的人机交互,尤其是在现有的按钮上加一些动画的效果,例如鼠标移上去变大,移开还原 ...
 - 【Android】键盘的展开和收起
			
键盘的展开和收起主要使用到类InputMethodManager:http://developer.android.com/reference/android/view/inputmethod/Inp ...
 - C#生成不重复的随机数(转)
			
我们在做能自动生成试卷的考试系统时,常常需要随机生成一组不重复随机数的题目,在.net Framework中提供了一个专门用来产生随机数的类System.Random. 对于随机数,大家都知道,计算机 ...
 - 疯狂的ASP.NET系列-第一篇:啥是ASP.NET
			
最近想学下ASP.NET,于是在网店上看到一本书叫做ASP.NET高级程序设计,老婆在旁边问了句:“这个不是DSP(数字信号处理,大学读的电子,所以这个比较熟),是ASP啊,什么是ASP啊?”.我想了 ...
 - html5  自定义数据属性 ,也就是 data-* 自定义属性---笔记。
			
html5 自定义数据属性 ,也就是 data-* 自定义属性. 例如 <div data-last-value="43" data-hidden="true& ...
 - CSS3伪类和伪元素的特性和区别
			
前端er们大都或多或少地接触过CSS伪类和伪元素,比如最常见的:focus,:hover以及<a>标签的:link.visited等,伪元素较常见的比如:before.:after等. 其 ...
 - Vex – 超轻量!可以轻松自定义的现代风格弹窗插件
			
Vex 的独特之处在于现代风格设计,能够自定义弹出模式.皮肤.Vex 超轻量,压缩后不到 2KB,提供了简洁的 API,可以根据自己的项目需要快速自定义.支持在移动设备上使用,测试通过的浏览器:IE8 ...
 - Hadoop下面WordCount运行详解
			
单词计数是最简单也是最能体现MapReduce思想的程序之一,可以称为MapReduce版"Hello World",该程序的完整代码可以在Hadoop安装包的"src/ ...