[comment]: # 学习Scala: 初学者应该了解的知识

Scala开发参照清单

这里列出在开发一个Scala工程中需要参照的资料。

官网网站

http://www.scala-lang.org/

文档网站

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

https://wiki.scala-lang.org

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

请看Scala Collection简介

Mutability vs Immutability

可变的变量(Mutable variables)(主要是可变的对象)会引起一些潜在的问题:

  • 变化后,可能在map中找不到了
  • 性能损失(在多线程下,读写需要加锁)

编程方面的建议是:

  • 如果可能,使用和开发 immutable 类。

杂七杂八

_ 的用途

请请看Scala underscore的用途

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: 初学者应该了解的知识的更多相关文章

  1. 如何快速学习Scala

    大数据学习过程中,会学习非常多的技术,但SCALA无疑是必不可少,那我们在大数据技术的学习过程中,如何快速的认识scala,并且学习它,感谢科多大数据公司的余老师提供的详细素材,本人整理成章,希望对你 ...

  2. 学习 shell脚本之前的基础知识

    转载自:http://www.92csz.com/study/linux/12.htm  学习 shell脚本之前的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写sh ...

  3. 学习Scala第一篇-从hello World开始

    最近开始系统性的学习scala.其实之前使用过scala的,比如我在用Gatling这款性能测试工具的时候就接触到了scala了.Gatling本身就是用Scala写的,而且Gatling的性能测试配 ...

  4. 怎样学习Scala泛函编程

    确切来说应该是我打算怎么去学习Scala泛函编程.在网上找不到系统化完整的Scala泛函编程学习资料,只好把能找到的一些书籍.博客.演讲稿.论坛问答.技术说明等组织一下,希望能达到学习目的.关于Sca ...

  5. HTML+CSS学习笔记 (7) - CSS样式基本知识

    HTML+CSS学习笔记 (7) - CSS样式基本知识 内联式css样式,直接写在现有的HTML标签中 CSS样式可以写在哪些地方呢?从CSS 样式代码插入的形式来看基本可以分为以下3种:内联式.嵌 ...

  6. 【转载】salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句

    salesforce 零基础开发入门学习(二)变量基础知识,集合,表达式,流程控制语句 salesforce如果简单的说可以大概分成两个部分:Apex,VisualForce Page. 其中Apex ...

  7. 刚开始学习Javascript的一些基础小知识,从入门到崩溃,希望对大家有帮助(只适合初学者)

    一.简介 1.JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型,js不能操作文件. 重要的开始啦!!!!! 引入javascript: 行间js <d ...

  8. Python学习系列(二)(基础知识)

    Python基础语法 Python学习系列(一)(基础入门) 对于任何一门语言的学习,学语法是最枯燥无味的,但又不得不学,基础概念较繁琐,本文将不多涉及概念解释,用例子进行相关解析,适当与C语言对比, ...

  9. 大数据学习day23-----spark06--------1. Spark执行流程(知识补充:RDD的依赖关系)2. Repartition和coalesce算子的区别 3.触发多次actions时,速度不一样 4. RDD的深入理解(错误例子,RDD数据是如何获取的)5 购物的相关计算

    1. Spark执行流程 知识补充:RDD的依赖关系 RDD的依赖关系分为两类:窄依赖(Narrow Dependency)和宽依赖(Shuffle Dependency) (1)窄依赖 窄依赖指的是 ...

随机推荐

  1. SAP ECC MM 配置文档

    SAP ECC 6.0 Configuration Document Materials Management (MM) Table of Content TOC \o \h \z 1. Genera ...

  2. 带着问题学 Spring MVC 源码: 一、概述

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! 简单就好,生活可以很德国 Q:什么是 Spring MVC ? ※ Spring MVC 是 S ...

  3. C8051 SMBus 原理

    一.SMBus总线   SMBus串行I/O接口完全符合系统管理总线规范 1.1 版.它是一个双线的双向串行总线,与I2C串行总线兼容.系统控制器对总线的读写操作都是以字节为单位的,由SMBus接口自 ...

  4. xml和xsd架构文档相关知识

    1.使用架构(XSD)验证XML文件 2.使用自动生成工具: 工具目录:C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4. ...

  5. (转)Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)

      异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Application.LoadLevel(“yourScene ...

  6. Oracle Purchasing QUESTIONS AND ANSWERS

    Topic Summary Topic: CORRECTIONS: Corrections Topic: DELIVER: Receiving Delivery Topic: DROPSHIP: Dr ...

  7. ionic介绍

    ionic介绍 Ionic是一个前端的框架,帮助开发者使用HTML5, CSS3和JavaScript做出原生应用. The beautiful, open source front-end fram ...

  8. MongoDB入门三:MongoDB shell

    MongoDB shell MongDB shell是一个功能完备的Javascript解释器,可以运行Javascript程序.也可以用于连接MongoDB服务器,执行脚本,对数据库进行操作.类似于 ...

  9. Linux - 文本格式转换

    文本文档格式查看 Linux下的文档格式查看方法 cat -A <filename> | grep "^M$", 如果存在^M$字符就是Dos格式. Windows下的 ...

  10. python 在sublime 中的配置

    首先可以先装package control 方法——按ctrl+`,然后在命令行里复制粘贴以下代码, import urllib2,os;pf='Package Control.sublime-pac ...