线性代数sparkscala

This commit is contained in:
estomm
2019-12-01 00:12:39 +08:00
parent 750052a70d
commit d0ab89e556
45 changed files with 3999 additions and 3 deletions

127
Scala/1 基本语法.md Normal file
View File

@@ -0,0 +1,127 @@
# 基本语法
## 1 相关概念
对象:对象有属性和行为。例如:一只狗的状属性有:颜色,名字,行为有:叫、跑、吃等。对象是一个类的实例。
类:类是对象的抽象,而对象是类的具体实例。
方法:方法描述的基本的行为,一个类可以包含多个方法。
属性:每个对象都有它唯一的实例变量集合。对象的属性通过给字段赋值来创建。
## 2 基本语法
### 特点
区分大小写 - Scala是大小写敏感的这意味着标识Hello 和 hello在Scala中会有不同的含义。
类名 - 对于所有的类名的第一个字母要大写。
如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写。
示例class MyFirstScalaClass
方法名称 - 所有的方法名称的第一个字母用小写。
如果若干单词被用于构成方法的名称,则每个单词的第一个字母应大写。
示例def myMethodName()
程序文件名 - 程序文件的名称应该与对象名称完全匹配(新版本不需要了,但建议保留这种习惯)。
保存文件时应该保存它使用的对象名称记住Scala是区分大小写并追加".scala"为文件扩展名。 (如果文件名和对象名称不匹配,程序将无法编译)。
示例: 假设"HelloWorld"是对象的名称。那么该文件应保存为'HelloWorld.scala"
def main(args: Array[String]) - Scala程序从main()方法开始处理这是每一个Scala程序的强制程序入口部分。
### 标识符
Scala 可以使用两种形式的标志符,字符数字和符号。
字符数字使用字母或是下划线开头,后面可以接字母或是数字,符号"$"在 Scala 中也看作为字母。然而以"$"开头的标识符为保留的 Scala 编译器产生的标志符使用,应用程序应该避免使用"$"开始的标识符,以免造成冲突。
Scala 的命名规则采用和 Java 类似的 camel 命名规则,首字符小写,比如 toString。类名的首字符还是使用大写。此外也应该避免使用以下划线结尾的标志符以避免冲突。符号标志符包含一个或多个符号如+:? 等,比如:
+ ++ ::: < ?> :->
Scala 内部实现时会使用转义的标志符,比如:-> 使用 $colon$minus$greater 来表示这个符号。因此如果你需要在 Java 代码中访问:->方法,你需要使用 Scala 的内部名称 $colon$minus$greater。
混合标志符由字符数字标志符后面跟着一个或多个符号组成,比如 unary_+ 为 Scala 对+方法的内部实现时的名称。字面量标志符为使用"定义的字符串,比如 `x` `yield`
你可以在"之间使用任何有效的 Scala 标志符Scala 将它们解释为一个 Scala 标志符,一个典型的使用为 Thread 的 yield 方法, 在 Scala 中你不能使用 Thread.yield()是因为 yield 为 Scala 中的关键字, 你必须使用 Thread.`yield`()来使用这个方法。
### Scala 关键字
下表列出了 scala 保留关键字,我们不能使用以下关键字作为变量:
abstract case catch class
def do else extends
false final finally for
forSome if implicit import
lazy match new null
object override package private
protected return sealed super
this throw trait try
true type val var
while with yield
- : = =>
<- <: <% >:
# @
### Scala 注释
Scala 类似 Java 支持单行和多行注释。多行注释可以嵌套,但必须正确嵌套,一个注释开始符号对应一个结束符号。注释在 Scala 编译中会被忽略,实例如下:
object HelloWorld {
/* 这是一个 Scala 程序
* 这是一行注释
* 这里演示了多行注释
*/
def main(args: Array[String]) {
// 输出 Hello World
// 这是一个单行注释
println("Hello, world!")
}
}
### 空行和空格换行符
一行中只有空格或者带有注释Scala 会认为其是空行,会忽略它。标记可以被空格或者注释来分割。
Scala是面向行的语言语句可以用分号;结束或换行符。Scala 程序里,语句末尾的分号通常是可选的。如果你愿意可以输入一个,但若一行里仅 有一个语句也可不写。另一方面,如果一行里写多个语句那么分号是需要的。例如
val s = "菜鸟教程"; println(s)
## 3 包
### Scala 包
定义包
Scala 使用 package 关键字定义包在Scala将代码定义到某个包中有两种方式
第一种方法和 Java 一样,在文件的头定义包名,这种方法就后续所有代码都放在该包中。 比如:
package com.runoob
class HelloWorld
第二种方法有些类似 C#,如:
package com.runoob {
class HelloWorld
}
第二种方法,可以在一个文件中定义多个包。
### 引用
Scala 使用 import 关键字引用包。
import java.awt.Color // 引入Color
import java.awt._ // 引入包内所有成员
def handler(evt: event.ActionEvent) { // java.awt.event.ActionEvent
... // 因为引入了java.awt所以可以省去前面的部分
}
import语句可以出现在任何地方而不是只能在文件顶部。import的效果从开始延伸到语句块的结束。这可以大幅减少名称冲突的可能性。
如果想要引入包中的几个成员可以使用selector选取器
import java.awt.{Color, Font}
// 重命名成员
import java.util.{HashMap => JavaHashMap}
// 隐藏成员
import java.util.{HashMap => _, _} // 引入了util包的所有成员但是HashMap被隐藏了

202
Scala/10 数组.md Normal file
View File

@@ -0,0 +1,202 @@
# Scala数组
## 1 基本操作
### 声明数组
以下是 Scala 数组声明的语法格式:
var z:Array[String] = new Array[String](3)
var z = new Array[String](3)
### 处理数组
数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本的 for 循环。
以下实例演示了数组的创建,初始化等处理过程:
object Test {
def main(args: Array[String]) {
var myList = Array(1.9, 2.9, 3.4, 3.5)
// 输出所有数组元素
for ( x <- myList ) {
println( x )
}
// 计算数组所有元素的总和
var total = 0.0;
for ( i <- 0 to (myList.length - 1)) {
total += myList(i);
}
println("总和为 " + total);
// 查找数组中的最大元素
var max = myList(0);
for ( i <- 1 to (myList.length - 1) ) {
if (myList(i) > max) max = myList(i);
}
println("最大值为 " + max);
}
}
### 多维数组
多维数组一个数组中的值可以是另一个数组,另一个数组的值也可以是一个数组。矩阵与表格是我们常见的二维数组。
以上是一个定义了二维数组的实例:
var myMatrix = ofDim[Int](3,3)
实例中数组中包含三个数组元素,每个数组元素又含有三个值。
接下来我们来看一个二维数组处理的完整实例:
import Array._
object Test {
def main(args: Array[String]) {
var myMatrix = ofDim[Int](3,3)
// 创建矩阵
for (i <- 0 to 2) {
for ( j <- 0 to 2) {
myMatrix(i)(j) = j;
}
}
// 打印二维阵列
for (i <- 0 to 2) {
for ( j <- 0 to 2) {
print(" " + myMatrix(i)(j));
}
println();
}
}
}
### 合并数组
以下实例中,我们使用 concat() 方法来合并两个数组concat() 方法中接受多个数组参数:
import Array._
object Test {
def main(args: Array[String]) {
var myList1 = Array(1.9, 2.9, 3.4, 3.5)
var myList2 = Array(8.9, 7.9, 0.4, 1.5)
var myList3 = concat( myList1, myList2)
// 输出所有数组元素
for ( x <- myList3 ) {
println( x )
}
}
}
### 创建区间数组
以下实例中,我们使用了 range() 方法来生成一个区间范围内的数组。range() 方法最后一个参数为步长,默认为 1
import Array._
object Test {
def main(args: Array[String]) {
var myList1 = range(10, 20, 2)
var myList2 = range(10,20)
// 输出所有数组元素
for ( x <- myList1 ) {
print( " " + x )
}
println()
for ( x <- myList2 ) {
print( " " + x )
}
}
}
## 数组函数
Scala 数组方法
下表中为 Scala 语言中处理数组的重要方法,使用它前我们需要使用 import Array._ 引入包。
序号 方法和描述
1
def apply( x: T, xs: T* ): Array[T]
创建指定对象 T 的数组, T 的值可以是 Unit, Double, Float, Long, Int, Char, Short, Byte, Boolean。
2
def concat[T]( xss: Array[T]* ): Array[T]
合并数组
3
def copy( src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int ): Unit
复制一个数组到另一个数组上。相等于 Java's System.arraycopy(src, srcPos, dest, destPos, length)。
4
def empty[T]: Array[T]
返回长度为 0 的数组
5
def iterate[T]( start: T, len: Int )( f: (T) => T ): Array[T]
返回指定长度数组,每个数组元素为指定函数的返回值。
以上实例数组初始值为 0长度为 3计算函数为a=>a+1
scala> Array.iterate(0,3)(a=>a+1)
res1: Array[Int] = Array(0, 1, 2)
6
def fill[T]( n: Int )(elem: => T): Array[T]
返回数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。
7
def fill[T]( n1: Int, n2: Int )( elem: => T ): Array[Array[T]]
返回二数组,长度为第一个参数指定,同时每个元素使用第二个参数进行填充。
8
def ofDim[T]( n1: Int ): Array[T]
创建指定长度的数组
9
def ofDim[T]( n1: Int, n2: Int ): Array[Array[T]]
创建二维数组
10
def ofDim[T]( n1: Int, n2: Int, n3: Int ): Array[Array[Array[T]]]
创建三维数组
11
def range( start: Int, end: Int, step: Int ): Array[Int]
创建指定区间内的数组step 为每个元素间的步长
12
def range( start: Int, end: Int ): Array[Int]
创建指定区间内的数组
13
def tabulate[T]( n: Int )(f: (Int)=> T): Array[T]
返回指定长度数组,每个数组元素为指定函数的返回值,默认从 0 开始。
以上实例返回 3 个元素:
scala> Array.tabulate(3)(a => a + 5)
res0: Array[Int] = Array(5, 6, 7)
14
def tabulate[T]( n1: Int, n2: Int )( f: (Int, Int ) => T): Array[Array[T]]
返回指定长度的二维数组,每个数组元素为指定函数的返回值,默认从 0 开始。

1175
Scala/11 容器.md Normal file

File diff suppressed because it is too large Load Diff

242
Scala/12 类和对象.md Normal file
View File

@@ -0,0 +1,242 @@
# Scala 类和对象
## 1 基本概念
类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
我们可以使用 new 关键字来创建类的对象,实例如下:
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点: " + x);
println ("y 的坐标点: " + y);
}
}
Scala中的类不声明为public一个Scala源文件中可以有多个类。
以上实例的类定义了两个变量 x 和 y 一个方法move方法没有返回值。
Scala 的类定义可以有参数,称为类参数,如上面的 xc, yc类参数在整个类中都可以访问。
接着我们可以使用 new 来实例化类,并访问类中的方法和变量:
import java.io._
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点: " + x);
println ("y 的坐标点: " + y);
}
}
object Test {
def main(args: Array[String]) {
val pt = new Point(10, 20);
// 移到一个新的位置
pt.move(10, 10);
}
}
## 2 Scala 继承
Scala继承一个基类跟Java很相似, 但我们需要注意以下几点:
1、重写一个非抽象方法必须使用override修饰符。
2、只有主构造函数才可以往基类的构造函数里写参数。
3、在子类中重写超类的抽象方法时你不需要使用override关键字。
接下来让我们来看个实例:
class Point(xc: Int, yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点: " + x);
println ("y 的坐标点: " + y);
}
}
class Location(override val xc: Int, override val yc: Int,
val zc :Int) extends Point(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
println ("z 的坐标点 : " + z);
}
}
Scala 使用 extends 关键字来继承一个类。实例中 Location 类继承了 Point 类。Point 称为父类(基类)Location 称为子类。
override val xc 为重写了父类的字段。
继承会继承父类的所有属性和方法Scala 只允许继承一个父类。
实例如下:
import java.io._
class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
}
}
class Location(override val xc: Int, override val yc: Int,
val zc :Int) extends Point(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
println ("z 的坐标点 : " + z);
}
}
object Test {
def main(args: Array[String]) {
val loc = new Location(10, 20, 15);
// 移到一个新的位置
loc.move(10, 10, 5);
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
x 的坐标点 : 20
y 的坐标点 : 30
z 的坐标点 : 20
Scala重写一个非抽象方法必须用override修饰符。
class Person {
var name = ""
override def toString = getClass.getName + "[name=" + name + "]"
}
class Employee extends Person {
var salary = 0.0
override def toString = super.toString + "[salary=" + salary + "]"
}
object Test extends App {
val fred = new Employee
fred.name = "Fred"
fred.salary = 50000
println(fred)
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
Employee[name=Fred][salary=50000.0]
## 3 Scala 单例对象
在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object。
Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象它和类的区别是object对象不能带参数。
当单例对象与某个类共享同一个名称时他被称作是这个类的伴生对象companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类companion class。类和它的伴生对象可以互相访问其私有成员。
单例对象实例
import java.io._
class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
}
}
object Test {
def main(args: Array[String]) {
val point = new Point(10, 20)
printPoint
def printPoint{
println ("x 的坐标点 : " + point.x);
println ("y 的坐标点 : " + point.y);
}
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
x 的坐标点 : 10
y 的坐标点 : 20
## 4 伴生对象实例
/* 文件名Marker.scala
* author:菜鸟教程
* url:www.runoob.com
*/
// 私有构造方法
class Marker private(val color:String) {
println("创建" + this)
override def toString(): String = "颜色标记:"+ color
}
// 伴生对象,与类名字相同,可以访问类的私有属性和方法
object Marker{
private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"),
"blue" -> new Marker("blue"),
"green" -> new Marker("green")
)
def apply(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def getMarker(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def main(args: Array[String]) {
println(Marker("red"))
// 单例函数调用,省略了.(点)符号
println(Marker getMarker "blue")
}
}
执行以上代码,输出结果为:
$ scalac Marker.scala
$ scala Marker
创建颜色标记red
创建颜色标记blue
创建颜色标记green
颜色标记red
颜色标记blue

64
Scala/13 Trait.md Normal file
View File

@@ -0,0 +1,64 @@
# Scala Trait(特征)
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。
与接口不同的是,它还可以定义属性和方法的实现。
一般情况下Scala的类只能够继承单一父类但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。
Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait如下所示
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
以上Trait(特征)由两个方法组成isEqual 和 isNotEqual。isEqual 方法没有定义方法的实现isNotEqual定义了方法的实现。子类继承特征可以实现未被实现的方法。所以其实 Scala Trait(特征)更像 Java 的抽象类。
以下演示了特征的完整实例:
/* 文件名Test.scala
* author:菜鸟教程
* url:www.runoob.com
*/
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
class Point(xc: Int, yc: Int) extends Equal {
var x: Int = xc
var y: Int = yc
def isEqual(obj: Any) =
obj.isInstanceOf[Point] &&
obj.asInstanceOf[Point].x == x
}
object Test {
def main(args: Array[String]) {
val p1 = new Point(2, 3)
val p2 = new Point(2, 4)
val p3 = new Point(3, 3)
println(p1.isNotEqual(p2))
println(p1.isNotEqual(p3))
println(p1.isNotEqual(2))
}
}
执行以上代码,输出结果为:
$ scalac Test.scala
$ scala Test
false
true
true
特征构造顺序
特征也可以有构造器,由字段的初始化和其他特征体中的语句构成。这些语句在任何混入该特征的对象在构造时都会被执行。
构造器的执行顺序:
调用超类的构造器;
特征构造器在超类构造器之后、类构造器之前执行;
特征由左到右被构造;
每个特征当中,父特征先被构造;
如果多个特征共有一个父特征,父特征不会被重复构造
所有特征被构造完毕,子类被构造。
构造器的顺序是类的线性化的反向。线性化是描述某个类型的所有超类型的一种技术规格。

34
Scala/2 数据类型.md Normal file
View File

@@ -0,0 +1,34 @@
# 数据类型
## 1 数据类型
### Scala 数据类型
Scala 与 Java有着相同的数据类型下表列出了 Scala 支持的数据类型:
数据类型 描述
Byte 8位有符号补码整数。数值区间为 -128 到 127
Short 16位有符号补码整数。数值区间为 -32768 到 32767
Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
Float 32 位, IEEE 754 标准的单精度浮点数
Double 64 位 IEEE 754 标准的双精度浮点数
Char 16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
String 字符序列
Boolean true或false
Unit 表示无值和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值写成()。
Null null 或空引用
Nothing Nothing类型在Scala的类层级的最底端它是任何其他类型的子类型。
Any Any是所有其他类的超类
AnyRef AnyRef类是Scala里所有引用类(reference class)的基类
### 转义字符
转义字符 Unicode 描述
\b \u0008 退格(BS) ,将当前位置移到前一列
\t \u0009 水平制表(HT) 跳到下一个TAB位置
\n \u000a 换行(LF) ,将当前位置移到下一行开头
\f \u000c 换页(FF),将当前位置移到下页开头
\r \u000d 回车(CR) ,将当前位置移到本行开头
\" \u0022 代表一个双引号(")字符
\' \u0027 代表一个单引号(')字符
\\ \u005c 代表一个反斜线字符 '\'

51
Scala/3 变量常量.md Normal file
View File

@@ -0,0 +1,51 @@
# Scala 变量
### 变量的作用
变量是一种使用方便的占位符,用于引用计算机内存地址,变量创建后会占用一定的内存空间。
基于变量的数据类型,操作系统会进行内存分配并且决定什么将被储存在保留内存中。因此,通过给变量分配不同的数据类型,你可以在这些变量中存储整数,小数或者字母。
### 变量声明
在学习如何声明变量与常量之前,我们先来了解一些变量与常量。
一、变量: 在程序运行过程中其值可能发生改变的量叫做变量。如:时间,年龄。
二、常量 在程序运行过程中其值不会发生变化的量叫做常量。如:数值 3字符'A'。
在 Scala 中,使用关键词 "var" 声明变量,使用关键词 "val" 声明常量。
声明变量实例如下:
var myVar : String = "Foo"
var myVar : String = "Too"
以上定义了变量 myVar我们可以修改它。
声明常量实例如下:
val myVal : String = "Foo"
以上定义了常量 myVal它是不能修改的。如果程序尝试修改常量 myVal 的值,程序将会在编译时报错。
### 变量类型声明
只声明类型不给值。
变量的类型在变量名之后等号之前声明。定义变量的类型的语法格式如下:
var VariableName : DataType [= Initial Value]
val VariableName : DataType [= Initial Value]
### 变量类型引用
在 Scala 中声明变量和常量不一定要指明数据类型,在没有指明数据类型的情况下,其数据类型是通过变量或常量的初始值推断出来的。
所以,如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值,否则将会报错。
var myVar = 10;
val myVal = "Hello, Scala!";
### cala 多个变量声明
Scala 支持多个变量的声明:
val xmax, ymax = 100 // xmax, ymax都声明为100
如果方法返回值是元组,我们可以使用 val 来声明一个元组:
scala> val pa = (40,"Foo")
pa: (Int, String) = (40,Foo)

View File

@@ -0,0 +1,87 @@
# Scala 访问修饰符
Scala 访问修饰符基本和Java的一样分别有privateprotectedpublic。
如果没有指定访问修饰符默认情况下Scala 对象的访问级别都是 public。
Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员。
## 1 私有(Private)成员
用 private 关键字修饰,带有此标记的成员仅在包含了成员定义的类或对象内部可见,同样的规则还适用内部类。
class Outer{
class Inner{
private def f(){println("f")}
class InnerMost{
f() // 正确
}
}
(new Inner).f() //错误
}
(new Inner).f( ) 访问不合法是因为 f 在 Inner 中被声明为 private而访问不在类 Inner 之内。
但在 InnerMost 里访问 f 就没有问题的,因为这个访问包含在 Inner 类之内。
Java中允许这两种访问因为它允许外部类访问内部类的私有成员。
## 2 保护(Protected)成员
在 scala 中对保护Protected成员的访问比 java 更严格一些。因为它只允许保护成员在定义了该成员的的类的子类中被访问。而在java中用protected关键字修饰的成员除了定义了该成员的类的子类可以访问同一个包里的其他类也可以进行访问。
package p{
class Super{
protected def f() {println("f")}
}
class Sub extends Super{
f()
}
class Other{
(new Super).f() //错误
}
}
上例中Sub 类对 f 的访问没有问题,因为 f 在 Super 中被声明为 protected而 Sub 是 Super 的子类。相反Other 对 f 的访问不被允许,因为 other 没有继承自 Super。而后者在 java 里同样被认可,因为 Other 与 Sub 在同一包里。
## 3 公共(Public)成员
Scala中如果没有指定任何的修饰符则默认为 public。这样的成员在任何地方都可以被访问。
class Outer {
class Inner {
def f() { println("f") }
class InnerMost {
f() // 正确
}
}
(new Inner).f() // 正确因为 f() 是 public
}
## 4 作用域保护
Scala中访问修饰符可以通过使用限定词强调。格式为:
private[x]
protected[x]
这里的x指代某个所属的包、类或单例对象。如果写成private[x],读作"这个成员除了对[…]中的类或[…]中的包中的类及它们的伴生对像可见外对其它所有类都是private。
这种技巧在横跨了若干包的大型项目中非常有用,它允许你定义一些在你项目的若干子包中可见但对于项目外部的客户却始终不可见的东西。
package bobsrockets{
package navigation{
private[bobsrockets] class Navigator{
protected[navigation] def useStarChart(){}
class LegOfJourney{
private[Navigator] val distance = 100
}
private[this] var speed = 200
}
}
package launch{
import navigation._
object Vehicle{
private[launch] val guide = new Navigator
}
}
}
上述例子中类Navigator被标记为private[bobsrockets]就是说这个类对包含在bobsrockets包里的所有的类和对象可见。
比如说从Vehicle对象里对Navigator的访问是被允许的因为对象Vehicle包含在包launch中而launch包在bobsrockets中相反所有在包bobsrockets之外的代码都不能访问类Navigator。

109
Scala/5 运算符.md Normal file
View File

@@ -0,0 +1,109 @@
# Scala 运算符
一个运算符是一个符号,用于告诉编译器来执行指定的数学运算和逻辑运算。
Scala 含有丰富的内置运算符,包括以下几种类型:
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
## 1 算术运算符
下表列出了 Scala 支持的算术运算符。
假定变量 A 为 10B 为 20
运算符 描述 实例
+ 加号 A + B 运算结果为 30
- 减号 A - B 运算结果为 -10
* 乘号 A * B 运算结果为 200
/ 除号 B / A 运算结果为 2
% 取余 B % A 运算结果为 0
## 2 关系运算符
下表列出了 Scala 支持的关系运算符。
假定变量 A 为 10B 为 20
运算符 描述 实例
== 等于 (A == B) 运算结果为 false
!= 不等于 (A != B) 运算结果为 true
> 大于 (A > B) 运算结果为 false
< 小于 (A < B) 运算结果为 true
>= 大于等于 (A >= B) 运算结果为 false
<= 小于等于 (A <= B) 运算结果为 true
## 3 逻辑运算符
下表列出了 Scala 支持的逻辑运算符。
假定变量 A 为 1B 为 0
运算符 描述 实例
&& 逻辑与 (A && B) 运算结果为 false
|| 逻辑或 (A || B) 运算结果为 true
! 逻辑非 !(A && B) 运算结果为 true
## 4 位运算符
位运算符用来对二进制位进行操作,~,&,|,^分别为取反,按位与与,按位与或,按位与异或运算,如下表实例:
p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
Scala 中的按位运算法则如下:
运算符 描述 实例
& 按位与运算符 (a & b) 输出结果 12 ,二进制解释: 0000 1100
| 按位或运算符 (a | b) 输出结果 61 ,二进制解释: 0011 1101
^ 按位异或运算符 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
~ 按位取反运算符 (~a ) 输出结果 -61 ,二进制解释: 1100 0011 在一个有符号二进制数的补码形式。
<< 左移动运算符 a << 2 输出结果 240 ,二进制解释: 1111 0000
>> 右移动运算符 a >> 2 输出结果 15 ,二进制解释: 0000 1111
>>> 无符号右移 A >>>2 输出结果 15, 二进制解释: 0000 1111
## 5 赋值运算符
以下列出了 Scala 语言支持的赋值运算符:
运算符 描述 实例
= 简单的赋值运算,指定右边操作数赋值给左边的操作数。 C = A + B 将 A + B 的运算结果赋值给 C
+= 相加后再赋值,将左右两边的操作数相加后再赋值给左边的操作数。 C += A 相当于 C = C + A
-= 相减后再赋值,将左右两边的操作数相减后再赋值给左边的操作数。 C -= A 相当于 C = C - A
*= 相乘后再赋值,将左右两边的操作数相乘后再赋值给左边的操作数。 C *= A 相当于 C = C * A
/= 相除后再赋值,将左右两边的操作数相除后再赋值给左边的操作数。 C /= A 相当于 C = C / A
%= 求余后再赋值,将左右两边的操作数求余后再赋值给左边的操作数。 C %= A is equivalent to C = C % A
<<= 按位左移后再赋值 C <<= 2 相当于 C = C << 2
>>= 按位右移后再赋值 C >>= 2 相当于 C = C >> 2
&= 按位与运算后赋值 C &= 2 相当于 C = C & 2
^= 按位异或运算符后再赋值 C ^= 2 相当于 C = C ^ 2
|= 按位或运算后再赋值 C |= 2 相当于 C = C | 2
## 6 运算符优先级
取决于所属的运算符组,它会影响算式的的计算。
实例: x = 7 + 3 * 2; 这里, x 计算结果为 13, 而不是 20因为乘法* 高于加法(+, 所以它先计算 3*2 再加上 7。
查看以下表格,优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。
类别 运算符 关联性
1 () [] 左到右
2 ! ~ 右到左
3 * / % 左到右
4 + - 左到右
5 >> >>> << 左到右
6 > >= < <= 左到右
7 == != 左到右
8 & 左到右
9 ^ 左到右
10 | 左到右
11 && 左到右
12 || 左到右
13 = += -= *= /= %= >>= <<= &= ^= |= 右到左
14 , 左到右

56
Scala/6 控制结构.md Normal file
View File

@@ -0,0 +1,56 @@
# 控制结构
## 1 IF选择
Scala IF...ELSE 语句是通过一条或多条语句的执行结果True或者False来决定执行的代码块。
* if 语句。if 语句有布尔表达式及之后的语句块组成。
* if...else 语句。if 语句后可以紧跟 else 语句else 内的语句块可以在布尔表达式为 false 的时候执行。
* if...else if...else 语句。if 语句后可以紧跟 else if...else 语句,在多个条件判断语句的情况下很有用。
* if...{if...else...}...else... 嵌套语句。if...else 嵌套语句可以实现在 if 语句内嵌入一个或多个 if 语句。
## 2 循环
### 循环类型
Scala 语言提供了以下几种循环类型。点击链接查看每个类型的细节。
循环类型 描述
while 循环 运行一系列语句如果条件为true会重复运行直到条件变为false。
do...while 循环 类似 while 语句区别在于判断循环条件之前,先执行一次循环的代码块。
for 循环 用来重复执行一系列语句直到达成特定条件达成,一般通过在每次循环完成后增加计数器的值来实现。
### while 循环
Scala 语言中 while 循环的语法:
while(condition)
{
statement(s);
}
在这里statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。
condition 可以是任意的表达式,当为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时,退出循环,程序流将继续执行紧接着循环的下一条语句。
### for循环
语法
Scala 语言中 for 循环的语法:
for( var x <- Range ){
statement(s);
}
### do while循环
Scala 语言中 while 循环的语法:
do {
statement(s);
} while( condition );
### 循环控制语句
循环控制语句改变你代码的执行顺序通过它你可以实现代码的跳转。Scala 以下几种循环控制语句:
Scala 不支持 break 或 continue 语句,但从 2.8 版本后提供了一种中断循环的方式,点击以下链接查看详情。
控制语句 描述
break 语句 中断循环

63
Scala/7 函数.md Normal file
View File

@@ -0,0 +1,63 @@
# 方法函数
## 1 方法与函数关系
Scala 有方法与函数二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。
Scala 中的方法跟 Java 的类似,方法是组成类的一部分。
Scala 中的函数则是一个完整的对象Scala 中的函数其实就是继承了 Trait 的类的对象。
Scala 中使用 val 语句可以定义函数def 语句定义方法。
class Test{
def m(x: Int) = x + 3
val f = (x: Int) => x + 3
}
## 2 函数
### 类型变量混合式
val f1 = (x:Int,y:Int)=>x*y
### 类型变量分离式
val f2:(Int,Int)=>Int = (x,y)=>x*y
## 3 方法
### 方法声明
Scala 方法声明格式如下:
def functionName ([参数列表]) : [return type]
如果你不写等于号和方法主体,那么方法会被隐式声明为抽象(abstract),包含它的类型于是也是一个抽象类型。
### 方法定义
方法定义由一个 def 关键字开始,紧接着是可选的参数列表,一个冒号 : 和方法的返回类型,一个等于号 = ,最后是方法的主体。
Scala 方法定义格式如下:
def functionName ([参数列表]) : [return type] = {
function body
return [expr]
}
object add{
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
### 方法调用
Scala 提供了多种不同的方法调用方式:
以下是调用方法的标准格式:
functionName( 参数列表 )
如果方法使用了实例的对象来调用我们可以使用类似java的格式 (使用 . 号)
[instance.]functionName( 参数列表 )

29
Scala/8 闭包.md Normal file
View File

@@ -0,0 +1,29 @@
# Scala 闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
闭包通常来讲可以简单的认为是可以访问一个函数里面局部变量的另外一个函数。
如下面这段匿名的函数:
val multiplier = (i:Int) => i * 10
函数体内有一个变量 i它作为函数的一个参数。如下面的另一段代码
val multiplier = (i:Int) => i * factor
在 multiplier 中有两个变量i 和 factor。其中的一个 i 是函数的形式参数,在 multiplier 函数被调用时i 被赋予一个新的值。然而factor不是形式参数而是自由变量考虑下面代码
var factor = 3
val multiplier = (i:Int) => i * factor
这里我们引入一个自由变量 factor这个变量定义在函数外面。
这样定义的函数变量 multiplier 成为一个"闭包",因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。
完整实例
object Test {
def main(args: Array[String]) {
println( "muliplier(1) value = " + multiplier(1) )
println( "muliplier(2) value = " + multiplier(2) )
}
var factor = 3
val multiplier = (i:Int) => i * factor
}

289
Scala/9 字符串.md Normal file
View File

@@ -0,0 +1,289 @@
# 字符串
## 1 简介
在 Scala 中,字符串的类型实际上是 Java String它本身没有 String 类。
在 Scala 中String 是一个不可变的对象,所以该对象不可被修改。这就意味着你如果修改字符串就会产生一个新的字符串对象。
但其他对象,如数组就是可变的对象。接下来我们会为大家介绍常用的 java.lang.String 方法。
## 2 常用方法
### 创建字符串
创建字符串实例如下:
var greeting = "Hello World!";
var greeting:String = "Hello World!";
### 字符串长度
我们可以使用 length() 方法来获取字符串长度:
object Test {
def main(args: Array[String]) {
var palindrome = "www.runoob.com";
var len = palindrome.length();
println( "String Length is : " + len );
}
}
### 字符串连接
String 类中使用 concat() 方法来连接两个字符串:
string1.concat(string2);
### 创建格式化字符串
String 类中你可以使用 printf() 方法来格式化字符串并输出String format() 方法可以返回 String 对象而不是 PrintStream 对象。以下实例演示了 printf() 方法的使用:
object Test {
def main(args: Array[String]) {
var floatVar = 12.456
var intVar = 2000
var stringVar = "菜鸟教程!"
var fs = printf("浮点型变量为 " +
"%f, 整型变量为 %d, 字符串为 " +
" %s", floatVar, intVar, stringVar)
println(fs)
}
}
### 常用方法
String 方法
下表列出了 java.lang.String 中常用的方法,你可以在 Scala 中使用:
序号 方法及描述
1
char charAt(int index)
返回指定位置的字符
2
int compareTo(Object o)
比较字符串与对象
3
int compareTo(String anotherString)
按字典顺序比较两个字符串
4
int compareToIgnoreCase(String str)
按字典顺序比较两个字符串,不考虑大小写
5
String concat(String str)
将指定字符串连接到此字符串的结尾
6
boolean contentEquals(StringBuffer sb)
将此字符串与指定的 StringBuffer 比较。
7
static String copyValueOf(char[] data)
返回指定数组中表示该字符序列的 String
8
static String copyValueOf(char[] data, int offset, int count)
返回指定数组中表示该字符序列的 String
9
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束
10
boolean equals(Object anObject)
将此字符串与指定的对象比较
11
boolean equalsIgnoreCase(String anotherString)
将此 String 与另一个 String 比较,不考虑大小写
12
byte getBytes()
使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
13
byte[] getBytes(String charsetName
使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
14
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此字符串复制到目标字符数组
15
int hashCode()
返回此字符串的哈希码
16
int indexOf(int ch)
返回指定字符在此字符串中第一次出现处的索引
17
int indexOf(int ch, int fromIndex)
返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索
18
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
19
int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
20
String intern()
返回字符串对象的规范化表示形式
21
int lastIndexOf(int ch)
返回指定字符在此字符串中最后一次出现处的索引
22
int lastIndexOf(int ch, int fromIndex)
返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索
23
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引
24
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
25
int length()
返回此字符串的长度
26
boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式
27
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
测试两个字符串区域是否相等
28
boolean regionMatches(int toffset, String other, int ooffset, int len)
测试两个字符串区域是否相等
29
String replace(char oldChar, char newChar)
返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的
30
String replaceAll(String regex, String replacement
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串
31
String replaceFirst(String regex, String replacement)
使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串
32
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串
33
String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串
34
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始
35
boolean startsWith(String prefix, int toffset)
测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
36
CharSequence subSequence(int beginIndex, int endIndex)
返回一个新的字符序列,它是此序列的一个子序列
37
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的一个子字符串
38
String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的一个子字符串
39
char[] toCharArray()
将此字符串转换为一个新的字符数组
40
String toLowerCase()
使用默认语言环境的规则将此 String 中的所有字符都转换为小写
41
String toLowerCase(Locale locale)
使用给定 Locale 的规则将此 String 中的所有字符都转换为小写
42
String toString()
返回此对象本身(它已经是一个字符串!)
43
String toUpperCase()
使用默认语言环境的规则将此 String 中的所有字符都转换为大写
44
String toUpperCase(Locale locale)
使用给定 Locale 的规则将此 String 中的所有字符都转换为大写
45
String trim()
删除指定字符串的首尾空白符
46
static String valueOf(primitive data type x)
返回指定类型参数的字符串表示形式

4
Scala/参考文献.md Normal file
View File

@@ -0,0 +1,4 @@
* [菜鸟教程](https://www.runoob.com/scala/scala-tutorial.html)
* [scala详细教程](https://blog.csdn.net/wangshun_410/article/details/90759688#2.3%20IDEAScala%20%E6%8F%92%E4%BB%B6%E7%9A%84%E7%A6%BB%E7%BA%BF%E5%AE%89%E8%A3%85)
* [W3c教程](https://www.w3cschool.cn/scaladevelopmentguide/)
* [另外一个教程](https://www.cnblogs.com/lq0310/p/9840317.html)