目录
字符串插值
Vectors
枚举类
Operator
可见性
元祖
ToString
模式匹配
字符串插值
- 在字符串的前面放一个s,在想让Scala插值的标识符之前放置一个$
- 任何以$为先导的标识符都会被转换成字符串
- 将表达式置于${}之间来计算和转换该表达式
case class Sky(color: String)
object Interpolation {def i(s: String, n: Int, d: Double): String = s"first: $s, second: $n, third: $d"def f(n: Int): Int = {n * 2}def main(args: Array[String]): Unit ={println(i("hello", 9, 89.0))// 将表达式置于${}之间来计算和转换该表达式println(s"the result of f(7) is: ${f(7)}")println(s"""${new Sky("bule")}""")}
}
输出:
first: hello, second: 9, third: 89.0
the result of f(7) is: 14
Sky(bule)
Vectors
创建Vector对象时,没有使用new关键字,事实上,我们无法用new关键字来创建Vector对象,Scala使用圆括号在序列中进行索引,Vecotr可以存放不同类型的数据
val v4 = Vector(2, 9.0, 'i', "p")
println("v4_0: " + v4(0))
val v2 = Vector()
//println("v2 head " + v2.head) //报错 empty.head
//println("v2 tail " + v2.tail) //报错 empty.tail
val v3 = Vector(1)
println("v3 head " + v3.head)
println("v3 tail " + v3.tail) //v3 tail Vector()
枚举类
Scala 没有从语言层面上支持枚举,需要利用继承的方式实现枚举,继承的是Enumeration抽象类。然后通过内部对象Value来赋值每一个枚举的值,创建object不会以创建class的方式创建新类型,若我们想要将其当作类型处理,必须使用type关键字,声明枚举对外暴露的变量类型
object Level extends Enumeration{type Level = Value // 声明枚举对外暴露的变量类型val Overflow, High, Medium, Low, Empty = Value // protected final def Value Scala.Enumeration
}import Level._object EunmClass {// 要type Level = Value和import Level._一下,否则Level无法识别,Error: not found: type Level// 没有type Level = Value,依旧可以使用Overflow等def checkLevel(level: Level) = level match{case Overflow => ">>> Overflow"case other => s"Level $level"}def main(args: Array[String]): Unit ={// 没有type Level = Value下面是不会报错的Level.Overflowprintln(Level.maxId)val one = {for(n <- Range(0, Level.maxId)) yield (n, Level(n))}println(one) // Vector((0,Overflow), (1,High), (2,Medium), (3,Low), (4,Empty))val two = for(level <- Level.values) yield levelprintln(two) // Level.ValueSet(Overflow, High, Medium, Low, Empty)println(two.toIndexedSeq) // Vector(Overflow, High, Medium, Low, Empty)// 没有type Level = Value下面会报错println("======================")println(checkLevel(Level.Overflow))println(checkLevel(Overflow))println(checkLevel(Level.High))}
}
Operator
某些语言提供了操作复重载机制,即将一组挑选出来的字符保存下来,并赋予特殊的解析方式和行为。Scala使得所有字符都是平等的, 且处理所有方法的方式也是相同的,若他们碰巧看起来像操作符,也只是你的看法而已。因此,Scala没有提供重载操作符重载机制,而是选择了更加优雅的方式。
class SimpleTime(var hours: Int){
// def subtract(val other:SimpleTime){} // 报错,Error:identifier expected but 'val' found.def subtract(other: SimpleTime): SimpleTime ={
// var ans: SimpleTime = _ // 报错,局部变量必须初始化var ans: SimpleTime = new SimpleTime(0)ans.hours = hours - other.hoursans}def -(other: SimpleTime): SimpleTime ={var ans: SimpleTime = new SimpleTime(0)ans.hours = hours - other.hoursans}def -=(other: SimpleTime): SimpleTime ={hours -= other.hoursthis}
}
object Operator {def main(args: Array[String]): Unit ={val t1 = new SimpleTime(hours = 5);val t2 = new SimpleTime(12);println("=========subtract=========")println((t2.subtract(t1).hours))println((t2 subtract t1).hours)println("===========-==============")println((t2 - t1).hours) // 中缀法println(t2.-(t1).hours)println("==========(-=)============")println("t2.hours: " + t2.hours)t2 -= t1println("after -=, t2.hours: " + t2.hours)}
}
可见性
所有定义(值和方法)实际上会在执行类体的其他部分之前进行初始化。
用参数列表(主构造器)进行初始化的时候,如果想要变量在类外可见,需要显示的指定val或者var。默认的是val,内部不能进行修改,外部不能访问
class ClassArg1(a: Int, var name: String){// 所有定义(值和方法)实际上会在执行类体的其他部分之前进行初始化println(f)def f(): Int ={// a = a * 10 // 报错,Reassignment to vala * 10}
}class ClassArg2(var a: Int)
class ClassArg3(val a: Int)class VisibleClassArgs {def main(args: Array[String]){val ca = new ClassArg1(20, "PK")ca.fprintln("===================")// a在类的外部不可以访问,如果希望a在类的外部也可以看见,需要将其定义为参数列表中的val和var// println(ca.a)// 报错:value a is not a member of org.example.ch3.ClassArg1println(ca.name)}
}
元祖
通过将元素放到圆括号内创建元祖,且用元祖作为f的返回值。
将整个元祖捕获到单个val或var中,则可以通过._n这样的索引来选择每个元素,从1开始
case class Employee(name: String, ID: Int)
class Tuples{// 通过将元素放到圆括号内创建元祖,且用元祖作为f的返回值def f = (1, 3.14, "Mouse", false)def main(args: Array[String]): Unit ={/*** 单个val后面跟着一个由5个标识符构成的元祖,表示对f返回的元祖进行拆包*/val (a, b, c, d) = fprintln(s"$a $b $c $d")/*** 将整个元祖捕获到单个val或var中,则可以通过._n这样的索引来选择每个元素,从1开始*/val all = fprintln(all)println(all._1)println(all._4)println("===========case class===========")/*** 类似的形式拆包case类*/val empA = Employee("Bob", 1130)val Employee(name, id) = empAprintln(name)}
}
ToString
在创建case类时会自动创建toString的方法
只要对某个对象操作时,期望得到一个String,则Scala会通过调用toString方法默默的为该对象产生一个String表示。
case class Bicycle(riders: Int)
class Surrey(val a: String)
class Surrey2(val a: String){/*** 重写toString方法,用override关键词* @return*/override def toString = s"Surrey2 with $a"
}object ToStringClass {def main(args: Array[String]): Unit ={val two = Bicycle(2)println(two)val fancy = new Surrey("top")// 只要对某个对象操作时,期望得到一个String,// 则Scala会通过调用toString方法默默的为该对象产生一个String表示。// 不过这里的缺省的toString好像不能满足我们的需要,后面重写一下println(fancy) // org.example.ch3.Surrey@6bdf28bbval fancy2 = new Surrey2("top")println(fancy2)}
}
模式匹配
Java:对一个值进行条件判断,返回针对不同的条件进行不同的处理
变量 match {case value1 => 代码1case value2 => 代码2......case _ => 代码N}scala 不需要加break
?
// 加条件匹配
def judegGrade(name: String, grade: String): Unit={grade match{case "A" => println("Excellent ...") // scala 不需要加breakcase "B" => println("Good ...")case "C" => println("Just so so ...")case _ if(name == "lisi") => println(name + "You are a good boy, but....")case _ => println("You need work harder ...")}
}
// Array匹配
def greeting(array: Array[String]): Unit ={array match{case Array("zhangsan") => println("Hi:zhangsan")case Array(x, y) => println("Hi:" + x + " , " + y)case Array("zhangsan", _*) => println("Hi:zhangsan and other friends...")case _ => println("Hi: everybody")}
}
// List匹配
def greeting(list: List[String]): Unit ={//case "zhangsan" :: tail => println("list, Hi:zhangsan and other friends...")//放的位置不一样输出结果也不一样,因为按顺序匹配,第一次能匹配上,就不会再匹配了list match{ // 按顺序匹配,第一次能匹配上,就不会再匹配了,这个与函数的入参不一样case "zhangsan":: Nil => println("list, Hi:zhangsan")case "zhangsan" :: tail => println("list, Hi:zhangsan and other friends...")case x::y::Nil => println("list, Hi:" + x + " , " + y)
// case "zhangsan" :: tail => println("list, Hi:zhangsan and other friends...")case _ => println("list, Hi: everybody")}
}
// 类型匹配,Any可以匹配任何类型
def matchType(obj: Any): Unit = {obj match{case x: Int => println("Int")case s: String => println("String")case m: Map[_, _] => m.foreach(println)case _ => println("otherType")}
}
class Person
case class CTO(name: String, floor: String) extends Person
case class Employee(name: String, floor: String) extends Person
case class Other(name: String) extends Person
// case class模式匹配
def caseClassMatch(person: Person): Unit ={person match{case CTO(name, floor) => println("CTO name is: " + name + ", floor is: " + floor)case Employee(name, floor) => println("Employee name is: " + name + ", floor is: " + floor)case _ => println("other")}
}
// Some、None匹配
val grades = Map("PK" -> "A", "zhangsan" -> "C")
def getGrade(name: String): Unit ={val grade = grades.get(name)grade match{case Some(grade) => println(name + ": your grade is " + grade)case None => println("Sorry...")}
}
getGrade("PK")
getGrade("zhangsan")
getGrade("Lily")