来自 fair-jm.iteye.com 转截请注明出处
摘录的一些笔记 来源挺杂的
主要是coursera上 FP principle in Scala课程的笔记
内也许有诸多错误 欢迎指正
避免状态改变
函数是一等公民
求值策略
Call by name:先代入等使用时再求值
Call by value:先求值再代入
如果CBV能终止 那么CBN一定能终止 反过来不成立
例子:
def first(x:Int , y:Int) =x
def loop()=loop
first(1,loop)
那么CBN一定可以终止的 CBV不会
scala用的是CBV
scala也运行用CBN 在定义时用 =>
如下:
def constOne(x:Int,y: => Int) = 1
def ---> by-name 使用时求值
val ---> by-value 先求值
简单的例子:
def loop:Boolean=loop
用 def x=loop 直接返回
x:Boolean
而用
val x=loop
会因为无限循环而卡住
block:
{}
在block的变量只能在{}内可见
在block的变量会隐藏在{}外的同名变量
;可选 在同一行写多个表达式的时候要用
一个表达式写多行的话用()括起来
或者把运算符写在上一行的结尾
尾递归(tail recursion):
占用的栈空间是固定的 本次结果不依赖下一次
回溯过程调用
用@tailrec注解来说明函数是尾递归的(如果所给函数不是尾递归的 会报错)
构建高阶函数
参数里用
f:Int => Int 的形式 (参数是Int 返回Int)
匿名函数的写法:
(参数) => 函数体
{def f(x1:T1,...,xn:Tn)=E;f}
例子:
def a= (b:Int)=>b //> a: => Int => Int
a(2)
啊哈这里就很简单啦 有名函数用= 匿名函数用 =>
类型的话 就是 (参数) => 返回类型
一个完整的例子:
def f(fun:Int => Int,b:Int):Int= { def sum(acc:Int,e:Int):Int = { if(e==0) acc else sum(fun(e)+acc,e-1) } sum(0,b) } //> f: (fun: Int => Int, b: Int)Int f((a:Int)=>a*a,2)
curring
函数柯里化
def add(x:Int) = (y:Int) => x+y //> add: (x: Int)Int => Int
add(5) //> res2: Int => Int = <function1>
add(5)(1) //> res3: Int = 6
和:
def add(x:Int)(y:Int) = x+y //> add: (x: Int)(y: Int)Int
add(5)_ //> res2: Int => Int = <function1>
add(5)(1) //> res3: Int = 6
是等价的
也就是 def 函数名(参数1:类型1)....(参数n:类型n)=E 等同于 def 函数名(参数1:类型1) = (参数2:类型2) => ...(参数n:类型n) => E
def add=(x:Int)=>(y:Int) =>(z:Int)=> x+y+z //> add: => Int => (Int => (Int => Int))
等同与
def add(x:Int)(y:Int)(z:Int) = x+y+z //> addx: (x: Int)(y: Int)(z: Int)Int
数据结构:
class Rational(x:Int,y:Int){ def numer = x def denom = y }
方法默认是public的
要用私有的 加上private 就可以了
require(条件,"异常时显示")
不满足条件 抛出异常 字符串是错误时文字
scala中可以作为标识符的:
字母
符号
_
字母以符号结尾
例如:
x1 * +?%& vector_++ counter_=
运算符重载也是遵循原有的优先级:
从低到高如下:
所有的字母
|
^
&
< >
= !
:
+ -
* / %
所有的特殊字符
还有一点要注意的是...
*? *!的优先级等同于 *
一个完整的例子:
class Rational(x:Int,y:Int){ require(y!=0,"denominator must be nonzero") def this(x:Int) = this(x,1) private def gcd(a:Int,b:Int):Int = if (b==0) a else gcd(b,a%b) private val g=gcd(x,y) def numer = x / g def denom = y / g def <(that:Rational) = numer*that.denom < that.numer*denom def max(that:Rational) = if(this < that) that else this def + (that :Rational) = new Rational( numer*that.denom+ that.numer*denom, denom*that.denom ) def unary_- = new Rational( -numer, denom ) def - (that:Rational)= this + -that def * (that:Rational) = new Rational(numer*that.numer,denom*that.denom) override def toString=numer+"/"+denom }
请注意 对象之间的== 可以重载== 也可以重写equals方法(最好重写equals方法)
抽象类:
abstract class IntSet { def incl(x:Int):IntSet def contains(x:Int):Boolean }
继承依旧使用extends
抽象的方法可以不写override 但不抽象的一定要写override
用Object定义的就是单例
object Empty extends IntSet {
def incl(x:Int):IntSet = new NonEmpty(x,Empty,Empty)
def contains(x:Int):Boolean=false
override def toString="."
}
不能用new创建
动态绑定
import中
import week3.Rational
import week3.{Rational,Hello} //导入Rational和Hello
import week3._
默认导入的
scala
java.lang
scala.Predef中的单例
Int --> scala.Int
Boolean -->scala.Boolean
Object --> java.lang.Object
require --> scala.Predef.require
assert --> scala.Predef.assert
===========================================================================
trait
java和scala中都是单继承的
用trait的定义很类似abstract class
直接用trait代替abstract class就可以了
一个类可以实现多个traits 用 with
比interface更强 可以包括域和已实现的方法
trait不能有构造参数和类后面跟的type parameter(抽象类可以有)
===========================================================================
Scala.Any
Scala.AnyVal Scala.AnyRef
基本类型的基类 引用类型的基类
Scala.Nothing Scala.Null
top types:
Any 所有的基类
方法:'==' '!=' equals hashCode toString
AnyRef 所有引用类型的基类:
java.lang.Object的别名
AnyVal 所有基本类型的基类
底层:
Scala.Nothing是所有类的子类
作用:
1.函数异常返回时 返回Nothing
2.作为空集合的里的元素
Set[Nothing]
Scala抛出异常:
throw Exc
例子:def error(msg:String) = throw new Error(msg) //> error: (msg: String)Nothing
返回值就是Nothing
Null是所有引用类型的子类
null是Null类型的 所以所有的引用类型都可以用null来赋值 记住基本类型中不成立
===========================================================================
多态:
Cons-Lists
Nil
Cons
泛型:
[T]
可用于类也可用于方法
def singleton[T](elem:T) = new Cons[T](elem,new Nil[T])
使用:
singleton[Int](1)
singleton[Boolean](true)
因为scala支持类型推断 所以 也可以写成singleton(1) 没有问题
scala也是会进行泛型擦除的(type erasure)
多态:
subtyping 子类的实例就是基类的实例
generics 泛型
函数作为对象:
A=>B
和Scala.Functional[A,B]:
trait Function[A,B]{
def apply(x:A):B
}
等价关系:
(x:Int) => x*x
def apply(x:Int):Int = x*x
eta-expansion
函数调用 例子:
List(1,2)=List.apply(1,2)
object Function{ def apply[T](x:T):T=x } Function[Int](1) //> res0: Int = 1
===========================================================================
Type Bounds:
def assertAllPos[S<:IntSet](r:S) :S=
S<:T 表示 S是T的子类 封顶
S>:T表示 S是T的父类 封底
还有一种限制范围的
[S>:NonEmpty <:IntSet] 以NonEmpty为底 以IntSet为顶的
covariant
这个的意思是 如果List是convariant的
S<:T (S是T的子类)成立
那么List[S]<:List[T]也成立
covariant带来的问题:
NonEmpty[] a=new NonEmpty[]{new NonEmpty(1,Empty,Empty)}
IntSet[] b = a
b[0]=Empty
NonEmpty s=a[0]
Empty不是NonEmpty 若执行肯定会错
这里NonEmpty是Inset的子类 java中Array是covariant的
所以 第二行成立 但Empty不是NonEmpty
java中的解决方法是在创建Array的时候就放入一个表明最初创建类型的Tag
因为Empty不是NonEmpty类型的 所以 b[0]=Empty这句话就会报错(所以是个运行时的错误)
scala中的Array就不是corvariant的:
var x=Array[Any]()
var y=Array[Int](1,2)
x=y //这里报错 type mismatch; found : Array[Int] required: Array[Any]
里氏替换原则:
Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.
if S<:T then q(x:T)==true ==> q(y:S)==true
如果下A<:B 那么对B能进行的操作 对A也可以进行
或者说对于q(x) x是B类型的能工作 那么q(y) y是A类型的也能工作如果A<:B
也就是 父类型能做的 子类型也要能做
要达到这个 父类方法的参数类型要比子类的"窄"(父类的参数类型要是子类参数类型的子类) 但父类方法的返回值类型应该要比子类的"宽"
===========================================================================
scala:FP OOP
基本类型
Peano numbers
Variance
Scala中List是covariant的 而Array不是
因为List是不可变的 所以不存在一些插入的问题(如上面的java的例子) 而Array不是
关系:
C[T] A B 其中A <: B
若 C[A]<:C[B] C 是 covariant
若 C[A]>:C[B] C 是 cotravariant
如果 C[A]和C[B]没有父子关系 那么C是nonvariant
Scala中是允许你自己定义是否是variant的
class C[+A]{...} C是covariant
class C[-A]{...} C是contrvariant
class C[A] {...} C是nonvariant(默认)
if A2 <: A1 and B1<:B2 ,then
A1 => B1 <: A2 => B2
父类的参数更窄 返回更宽
variance check
因此 Scala会给标识为variant的类做限制:
covariant的类型只能作为返回值
cotrvariant的类型只能作为参数值
===========================================================================
===========================================================================
scala java
x.isInstanceOf[T] x instanceof T
x.asInstanceOf[T] (T)x
eval
Pattern Matching:
case class
e match{
case pattern => expr
}
在没有匹配项时抛出 MatchError
Pattern可以是:
小写字母开头表示变量(保留字除外) 用于绑定值到这个变量
大写开头表示常量 两者是否相等来进行匹配(==)
_
构造器pattern C(p1,....,pn) 匹配所有C类型(或子类型)通过p1...p构造的
(注意类的定义要用case class)
同样的变量只能在Pattern出现一次
顺序匹配下去
例子:
trait Expr { def isNumber: Boolean def isSum: Boolean def numValue: Int def leftOp: Expr def rightOp: Expr def show():String = this match{ case Number(n) => n+"" case Sum(e1,e2) => e1+"+"+e2 } }
另一个例子:
def show(e: Expr): String = e match { case Sum(Prod(x1, x2), Prod(x3, x4)) => if (x1 == x3) show(x1) + "*" + "(" + show(x2) + "+" + show(x4) + ")" else if (x1 == x4) show(x1) + "*" + "(" + show(x2) + "+" + show(x3) + ")" else if (x2 == x3) show(x2) + "*" + "(" + show(x1) + "+" + show(x4) + ")" else if (x2 == x4) show(x2) + "*" + "(" + show(x1) + "+" + show(x3) + ")" else show(_Prod(x1, x2)) + "+" + show(_Prod(x3, x4)) case Sum(n1, n2) => show(n1) + "+" + show(n2) case Prod(Sum(n1, n2), n3) => "(" + show(_Sum(n1, n2)) + ")" + "*" + show(n3) case Prod(n3, Sum(n1, n2)) => show(n3) + "*(" + show(_Sum(n1, n2)) + ")" case Prod(n1, n2) => show(n1) + "*" + show(n2) case _ => e.toString() }
Lists:
List("xxx","xxx") List[String]
List() List[Nothing]
List(1,2,3,4,5)
:: 是 scala的cons操作符
car :: cdt
"1"::("2"::("3"::Nil)) //> res1: List[String] = List(1, 2, 3)
scala中做了简化 所以 也可以写成"1"::"2"::"3"::Nil是等价的 (::其实是方法名 相当于调用方法 可以写成.::)
1 :: 2 :: 3 :: 4 :: Nil 和 Nil.::(4).::(3).::(2).::(1)
等价
List中一样有 head和tail方法
此外 两个List连接可以用:::
List(1,2,3):::List(4,5,6) //> res6: List[Int] = List(1, 2, 3, 4, 5, 6)
这个和List(4,5,6).:::(List(1,2,3))等价
List的模式:
Nil 表示空list
p :: ps 表示以p开头的元素 这个模式和[Head|Tail]一致
List(p1,...,p2) 也可以写成 p1::....::pn::Nil
当然也可以用_
例子:
List(1,2,3) match {
case List(1,_,3) => "yes" //这样其实也是一种构造模式吧
} //> res2: String = yes
更多用于List的函数:
xs.length
xs.last 获得最后一个
xs.init 得到一个除了最后一个元素的列表
xs take n
xs drop n
xs(n)
scala> def xs= List(0,1,2,3,4) xs: List[Int] scala> xs.length res0: Int = 5 scala> xs.last res1: Int = 4 scala> xs.init res2: List[Int] = List(0, 1, 2, 3) scala> xs take 1 res3: List[Int] = List(0) scala> xs drop 1 res4: List[Int] = List(1, 2, 3, 4) scala> xs(0) res5: Int = 0
创建新列表:
xs ++ ys 合并
xs.reverse 倒序
xs.updated(n,x)
查找元素:
xs indexOf x 不存在返回-1
xs contains x
tuple:
pair: (x,y)
scala> val (label,value) = (1,"s")
label: Int = 1
value: String = s
scala> (1,"s")
res0: (Int, String) = (1,s)
超过两个元素的就是tuple了
(T1,....,Tn)是Scala.Tuplen[T1,...,Tn]的缩写
(e1,....,en)是Scala.Tuplen(e1,...,en)的缩写
tuple模式中也和上面的(e1,...,en)一样
implicit:
在函数的参数中使用 编译器会根据类型得到正确的隐含参数
The compiler will ?gure out the right implicit to pass based on the demanded type.
def msort[T](xs:List[T])(implicit ord:Ordering)
调用时只需:
msort(List(1,2,3)) 或者msort(List("1","2","3"))
Ordering在scala.math包下 提供了常用的比较操作等
如何查找的:
? is marked implicit
? has a type compatible with T
? is visible at the point of the function call, or is de?ned in a
companion object associated with T.
以上的原则 Ordering是包含类型参数的 完整的形式是 Ordering[T]
所以编译器在使用List(1,2,3)时会正确找到Ordering[Int] 而为List("1","2","3")时则为Ordering[String]
def less[T](a:T,b:T)(implicit ord:math.Ordering[T]):Boolean=ord.lt(a, b)
less(1,2)
List的高阶函数
map
filter
span
takeWhile
dropWhile
fold/reduce:
List(x1,...,xn) reduceLeft op = (...(x1 op x2) op...) op xn
((x,y) => x*y)可以写成(_*_)
reduceLeft不能处理Nil 一般用foldLeft代替使用
(List(x1,...,xn) foldLeft z)(op) = (..(z op x1) op...) op xn
def sum(xs:List[Int]) = (xs foldLeft 0)(_+_)
以及foldRight
注意foldLeft和foldRight并不一定能通用
原因在于
foldLeft中 累加器在参数左
foldRight中 累加器在参数右
累加器的类型是U List的类型是T
foldLeft是:
U T
U T
U T
而foldRight则是
T U
T U
U T
也就是一个操作符的问题 例如:: 左边是要T的 而右边是List[T] 注意一下缩写的op函数就可以了
foldLeft中累加器是第一个参数 元素是第二个参数
foldRight中累加器是第二个参数 元素是第一个参数
其他的集合类:
都是不可变的
Vector 用Vector()c创建 +: :+ x+:xs xs:+x
默认32大小 如果不够用了 会增加一层 log32(N)
List和Vector的基类是Seq 所有sequences的基类
Seq是Iterable的子类
Iterable
Seq Set Map
String和Array也类似Seq(但不是子类) 他们一样可以用map fold 等方法
Ranges:
val r:Range = 1 until 5
val 3:Range = 1 to 5
1 to 10 by 3
6 to 1 by -2
Range中的域只有 上限 下限 步长
Range也可以用map fold等方法
for:
for (s) yield e //yield是将后面内容输出为一个List
s中可以写赋值(必须在第一项)和判断
如果有多个赋值 可以写成 {}的形式
mkString 把元素通过制定的字符连接成字符串 和groovy的join有点类似
for的转换:
for(x <- e1) yield e2 被转换成 e1 map(x=>e2)
等等
for的转换是基于 map flatMap withFilter的
ScalaQuery Slick
Map:
构建用Map(key -> value)
取出用get
如果不存在返回None 不然返回Some(x) 用模式【匹配获取
List: sortWith sorted
groupBy 返回的是Map
1 ->2 和 (1,2)是一样的:
scala> 1 -> 2 res5: (Int, Int) = (1,2) scala> (1,2) res6: (Int, Int) = (1,2) scala> Map((1,2)) res7: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
默认值:
用withDefaultValue方法 后面跟一个defaultValue 构建一个新的Map
Scala用*表示不定参数函数 例如:
def this(bindings:(Int,Double)*)=???
对于合适的数据 可以用toMap toList进行相互的转换
Map也可以作为函数 参数是key 返回值是value
操作总结:
Map:
- + map和元素之间
- ++ map和map之间 如果有相同的key 则以第二个map为准
- withDefaultValue 返回一个对于不存在key 有默认值的Map
- 1 -> 2 和 (1,2)等价
- 符合结构的Map和List可以互相转换
List:
- 元素 :: List cons构造(往前追加一个元素)
- List ++ List 合并
- List ::: List 合并
Stream:
构造 可以用Stream.empty 用Stream.cons方法进行构造
可以用 Stream(el1,...,eln)进行构造
也可以用 其他Seq的toStream方法进行构造
scala> Stream(1,2)
res0: scala.collection.immutable.Stream[Int] = Stream(1, ?)
注意后面是个? 第二个或者后面的还没用到就先不求值 结构和List是类似的
Stream基本支持List的方法 但有一个例外 Stream不支持 head :: tail 不过有另外一个选择 就是使用 #:: 同样:Stream.cons(x,xs)和 x #:: xs 一样
Lazy Evaluation 惰性求值
和 by-name 求值(每次用到的时候再求值) 和 strict求值 (先求值再使用) 不同
惰性求值在使用时计算并且以后使用的话用已计算好的值
scala支持惰性求值 使用lazy val 定义就可以了
scala> def eval_():Int = { | println("evalution") | 1 | } eval_: ()Int scala> def pp(i: =>Int) ={ | println(i);println(i); | } pp: (i: => Int)Unit scala> pp(eval_()) // by-name求值 evalution 1 evalution 1 scala> lazy val x=eval_() //惰性求值 x: Int = <lazy> scala> x evalution res11: Int = 1 scala> x res12: Int = 1 scala> def y =eval_() //def也是by-name求值 y: Int scala> y evalution res13: Int = 1 scala> y evalution res14: Int = 1
当然scala默认用的是strict求值
例子:
scala> def expr = { | val x = {print("x");1} | lazy val y = { print("y");2} | def z = {print("z");3} | z+y+x+z+y+x | } expr: Int scala> expr xzyzres15: Int = 12
Stream的cons就是使用的惰性求值:
scala> val s = Stream.cons(1,Stream({println("x");2})) s: Stream.Cons[Int] = Stream(1, ?) scala> s(1) x res21: Int = 2 scala> s(1) res22: Int = 2
用Stream可以构建无穷的数据(需要时取一部分就可以了)
===========================================================================
===========================================================================
一些语法:
循环:
while用法和java一样
for的语法是
for(i <- 初始值 until 终止值){
}
输出0-9:
for(i <- 0 until 10){ println(i) }
还可以用forEach
List(1,2,3,4,"string").foreach( i => println(i))
范围和元组
范围用
val ran= 初始值 until 终止值
默认步长为1 修改步长用 () by 步长:
val range=0 until 10 by 2 //> range : scala.collection.immutable.Range = Range(0, 2, 4, 6, 8)
range.size //> res1: Int = 5
range.start //> res2: Int = 0
range.end //> res3: Int = 10
range.step //> res4: Int = 2
或者用 to(包含终点)
val range=0 to 10 by 2 //> range : scala.collection.immutable.Range = Range(0, 2, 4, 6, 8, 10)
元祖依旧是用()
用._1取第一个元素以此类推 元祖可以用来进行多值赋值:
val (x,y)=(1,2) //> x : Int = 1
//| y : Int = 2
val tuple=(1,2) //> tuple : (Int, Int) = (1,2)
tuple._1 //> res1: Int = 1
一样可以用_做任意匹配
===========================================================================
===========================================================================
scala中方法和函数的区别
===========================================================================
方法的定义:
def m(x:Int):Int = x * 2
函数的定义:
def f= (x:Int) => x * 2
===========================================================================
有参数的方法不能写成 m 而函数则没有此限制:
scala> f res0: Int => Int = <function1> scala> m <console>:9: error: missing arguments for method m; follow this method with `_' if you want to treat it as a partially applied function m ^
===========================================================================
方法没有参数时可以不写() 而函数一定要写():
scala> def m = 2 m: Int scala> def f = =>2 <console>:1: error: illegal start of simple expression def f = =>2 ^
当然方法写了也可以:
scala> def m()= 2 m: ()Int
这样的情况下用 m 其实是调用了方法 而对于f 如果直接f则是返回函数本身
===========================================================================
Scala中含有 ETA expansion
所以可以将传递函数的地方直接传递方法 但是不能用于赋值: scala> val myList = List(3, 56, 1, 4, 72) myList: List[Int] = List(3, 56, 1, 4, 72) scala> myList.map((x)=>2*x) res1: List[Int] = List(6, 112, 2, 8, 144) scala> def m3(x: Int) = 3*x m3: (x: Int)Int scala> myList.map(m3) res2: List[Int] = List(9, 168, 3, 12, 216)
===========================================================================
方法强转为函数 使用_就可以了:
scala> def m4(x: Int) = 4*x m4: (x: Int)Int scala> val f4 = m4 _ //注意这边有个空格 但如果是方法做柯里化有个()就不用多加一个空格(加了也没关系) f4: Int => Int = <function1> scala> f4(2) res3: Int = 8 scala>
===========================================================================
//use "x" twice, meaning that the method is invoked twice.
scala> def m1(x: => Int) = List(x, x)
m1: (x: => Int)List[Int]
scala> import util.Random
import util.Random
scala> val r = new Random()
r: scala.util.Random = scala.util.Random@ad662c
//as the method is invoked twice, the two values are different.
scala> m1(r.nextInt)
res37: List[Int] = List(1317293255, 1268355315
翻译自:
http://java.dzone.com/articles/revealing-scala-magician%E2%80%99s
一些学习资料:
http://zh.scala-tour.com/#/welcome
http://twitter.github.io/scala_school/zh_cn/
http://twitter.github.io/effectivescala/index-cn.html
相关推荐
Scala学习笔记,大全笔记
在"scala学习笔记整理"中,我们可以深入探讨以下关键知识点: 1. **基础语法**:Scala的基础语法与Java有相似之处,但也有很多独特的特点。例如,它支持变量的不可变性(immutability),使用`val`声明常量,`var`...
### Scala学习笔记(全) #### 一、Scala概述与特点 Scala是一种多范式的编程语言,旨在集成面向对象编程和函数式编程的各种特性。它运行于Java平台(Java虚拟机JVM),并且能够完全兼容所有的Java程序。这使得Scala...
读书笔记:快学scala 笔记和习题
eclipse集成maven+scala笔记 本文主要讲述了如何在Eclipse中集成Maven和Scala,以便更好地进行Java开发。下面是相关知识点的总结: 一、JDK的下载和安装 * JDK是Java开发的基础环境,下载和安装JDK是开发的第一步...
Scala中的标识符遵循一定的规则,例如首字符不能是数字,区分大小写等。 #### 操作符 Scala支持多种操作符,包括算术操作符、关系操作符、逻辑操作符等。 #### 块表达式与赋值 在Scala中,块内的最后一个表达式的...
### Scala学习笔记关键知识点 #### 1. “均码”哲学与并发编程 - **“均码”哲学**: 指的是Scala设计时遵循的一种设计理念,即尽量保持语言的统一性和简洁性,使得不同的功能和特性能够以一种相似的方式进行处理。...
### Scala的操作笔记 #### 一、课程目标与学习路径 本课程旨在通过三个阶段的目标来逐步深入学习Scala语言,最终能够灵活运用Scala进行Spark程序的开发,并具备阅读Spark内核源码的能力。 - **初级目标**:掌握...
Scala学习资源Scala编程语言抓住了很多开发者的眼球。如果你粗略浏览Scala的网站,你会觉得Scala是一种纯粹的面向对象编程语言,而又无缝地结合了命令式编程和函数式编程风格。Christopher Diggins认为: 不太久...
scala基础知识笔记
ScalaOverview.pdf ScalaTutorial.pdf ProgrammingInScala.pdf(这本是书) 博文链接:https://dogstar.iteye.com/blog/182673
Scala是一种强大的多范式编程语言,它融合了面向对象和函数式编程的特性,被广泛应用于大数据处理、分布式计算和高性能应用开发。本压缩包包含五份PDF文档,旨在帮助初学者快速入门并逐步进阶Scala编程。 第一部分...
IDEA创建Scala项目: 创建一个Maven项目:在maven项目环境下进行编码 新建目录需要编译 目录-->右键-->Mark Dirctory as --->Source Root 作为源码(编译成功 目录颜色会从灰色变色浅绿色) 把项目和Scala...
自己整理的Scala语言的笔记,可能会存在失误等情况,请各位能够批评指正!我会及时修改!谢谢!
2. **Scala语言诞生小故事**: Scala由Martin Odersky教授在2001年创建,其初衷是为了克服Java的局限性,提供一种更现代、更灵活的编程语言。它结合了面向对象和函数式编程的优点,试图在单一语言中解决软件开发的...
读书笔记:《快学Scala》笔记和习题
[Scala学习笔记-中文资料] 从java角度看Scala
Scala3,也被称为Scala 3或Dotty,是Scala编程语言的一个重大更新,旨在提高其简洁性、可读性和类型安全性。Scala3的发布标志着该语言的进一步成熟,它引入了一系列改进,旨在解决早期版本中的一些痛点,同时保持对...
Scala SDK,全称为Scala Software Development Kit,是用于开发Scala应用程序的核心工具集。Scala是一种多范式的编程语言,融合了面向对象和函数式编程的特点,它运行在Java虚拟机(JVM)上,能够充分利用Java生态...