scala 编程思想-笔记

本文介绍了Scala编程中的字符串插值,展示了如何在字符串中插入变量和表达式的值。接着讨论了Vector,一种不可变的高效数组,以及如何使用它。枚举类在Scala中是通过继承Enumeration实现的,并通过Value来定义枚举值。此外,文章还讲解了Scala的操作符处理,可见性规则,元组的使用,toString方法的自动创建,以及模式匹配的概念和应用。
摘要由CSDN通过智能技术生成

目录

字符串插值

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.Overflow
    println(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 level
    println(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.hours
    ans
  }
  def -(other: SimpleTime): SimpleTime ={
    var ans: SimpleTime = new SimpleTime(0)
    ans.hours = hours - other.hours
    ans
  }
  def -=(other: SimpleTime): SimpleTime ={
    hours -= other.hours
    this
  }
}
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 -= t1
    println("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 val
    a * 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.f
    println("===================")
    // a在类的外部不可以访问,如果希望a在类的外部也可以看见,需要将其定义为参数列表中的val和var
    //    println(ca.a)// 报错:value a is not a member of org.example.ch3.ClassArg1
    println(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) = f
    println(s"$a $b $c $d")

    /**
     * 将整个元祖捕获到单个val或var中,则可以通过._n这样的索引来选择每个元素,从1开始
     */
    val all = f
    println(all)
    println(all._1)
    println(all._4)

    println("===========case class===========")
    /**
     * 类似的形式拆包case类
     */
    val empA = Employee("Bob", 1130)
    val Employee(name, id) = empA
    println(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@6bdf28bb

    val fancy2 = new Surrey2("top")
    println(fancy2)
  }
}

模式匹配

Java:对一个值进行条件判断,返回针对不同的条件进行不同的处理

变量 match {
  case value1 => 代码1
  case value2 => 代码2
  ......
  case _ => 代码N
 }
 scala 不需要加break

🌰

// 加条件匹配
def judegGrade(name: String, grade: String): Unit={
  grade match{
    case "A" => println("Excellent ...") // scala 不需要加break
    case "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")

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值