- tags: Programming Language
Scala 学习资源
Scala 这么好的语言为什么不流行
结论:Java 人才更多且成本更低。
Scala 工具
sbt
sbt new
无法处理替换过的 SSH 会导致 Auth fail,一个 workaround 就是手动 clone 项目然后:
sbt new file:///path/to/template.g8
sbt 国内加速
~/.sbt/repositories
:
[repositories]
local
nexus-aliyun:https://maven.aliyun.com/nexus/content/groups/public
nexus-aliyun-ivy:https://maven.aliyun.com/nexus/content/groups/public/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
typesafe: https://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
Unique Scala
Rust from Scala
Rust 和 Scala 有很多想通的地方,Rust 应该从 Scala 借鉴了很多:
- 可变量和不可变量
- 模式匹配
- Trait
内置类型
val b: Byte = 1
val x: Int = 1
val l: Long = 1
val s: Short = 1
val d: Double = 2.0
val f: Float = 3.0
字符串拼接
Python 也支持类似的 f-string
语法,在 Scala 中是 s-string
语法。
val firstName = "John"
val mi = 'C'
val lastName = "Doe"
val name = firstName + " " + mi + " " + lastName
val name = s"$firstName $mi $lastName"
println(s"Name: $firstName $mi $lastName")
println(s"Name: ${firstName} ${mi} ${lastName}")
println(s"1+1 = ${1+1}")
多行字符串
for 循环
val nums = Seq(1,2,3)
for (n <- nums) println(n)
val people = List(
"Bill",
"Candy",
"Karen",
"Leo",
"Regina"
)
for (p <- people) println(p)
// foreach
people.foreach(println)
// map foreach
val ratings = Map(
"Lady in the Water" -> 3.0,
"Snakes on a Plane" -> 4.0,
"You, Me and Dupree" -> 3.5
)
for ((name,rating) <- ratings) println(s"Movie: $name, Rating: $rating")
ratings.foreach {
case(movie, rating) => println(s"key: $movie, value: $rating")
}
for 表达式
val nums = Seq(1,2,3)
val doubledNums = for (n <- nums) yield n * 2 // <----- 注意 yield
see also: yield
模式匹配
Rust 和 Scala 很像,但是 Scala 依然有很多独特的地方:
// 模式匹配作为方法体
def convertBooleanToStringMessage(bool: Boolean): String = bool match {
case true => "you said true"
case false => "you said false"
}
// alternate cases
def isTrue(a: Any) = a match {
case 0 | "" => false
case _ => true
}
// 支持 if
count match {
case 1 => println("one, a lonely number")
case x if x == 2 || x == 3 => println("two's company, three's a crowd")
case x if x > 3 => println("4+, that's a party")
case _ => println("i'm guessing your number is zero or less")
}
异常捕获
异常捕获结合了模式匹配:
var text = ""
try {
text = openAndReadAFile(filename)
} catch {
case e: FileNotFoundException => println("Couldn't find that file.")
case e: IOException => println("Had an IOException trying to read that file")
}
方法定义
// 函数定义的基本语法
def sum(a: Int, b: Int): Int = a + b
def concatenate(s1: String, s2: String): String = s1 + s2
// 返回参数可以省略
def sum(a: Int, b: Int) = a + b
def concatenate(s1: String, s2: String) = s1 + s2
// 代码块用 {} 包围,但是 = 不能省略
def long(a: Int, b: Int) = {
a + b
}
类构造
class Person(var firstName: String, var lastName: String)
val p = new Person("Bill", "Panner")
// val 只读
class Person(val firstName: String, val lastName: String)
// 构造方法直接写在类体里
class Person(var firstName: String, var lastName: String) {
println("the constructor begins")
// 'public' access by default
var age = 0
// some class fields
private val HOME = System.getProperty("user.home")
// some methods
override def toString(): String = s"$firstName $lastName is $age years old"
def printHome(): Unit = println(s"HOME = $HOME")
def printFullName(): Unit = println(this)
printHome()
printFullName()
println("you've reached the end of the constructor")
}
// 其他一些例子
class Pizza (var crustSize: Int, var crustType: String)
// a stock, like AAPL or GOOG
class Stock(var symbol: String, var price: BigDecimal)
// a network socket
class Socket(val timeout: Int, val linger: Int) {
override def toString = s"timeout: $timeout, linger: $linger"
}
class Address (
var street1: String,
var street2: String,
var city: String,
var state: String
)
构造方法重载
val DefaultCrustSize = 12
val DefaultCrustType = "THIN"
// the primary constructor
class Pizza (var crustSize: Int, var crustType: String) {
// one-arg auxiliary constructor
def this(crustSize: Int) = {
this(crustSize, DefaultCrustType)
}
// one-arg auxiliary constructor
def this(crustType: String) = {
this(DefaultCrustSize, crustType)
}
// zero-arg auxiliary constructor
def this() = {
this(DefaultCrustSize, DefaultCrustType)
}
override def toString = s"A $crustSize inch pizza with a $crustType crust"
}