Scala实践9

1、特征

      Traits用于在类之间共享接口和字段。它们类似于Java 8的接口。类和对象可以扩展特征,但是特征不能被实例化,因此没有参数。

  • 定义一个特征

     最小特征只是关键字trait和标识符:

1
trait Color

 特征作为泛型类型和抽象方法特别有用。

1
2
3
4
trait Iterator[A] {
  def hasNext: Boolean
  def next(): A
}

  扩展(与Java中的实现类似)trait Iterator[A]需要一个类型A和方法实现hasNextnext

 

  • 使用特征

       使用extends关键字来扩展特征。然后使用override关键字实现特征的任何抽象成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
trait Iterator[A] {
  def hasNext: Boolean
  def next(): A
}
 
class IntIterator(to: Int) extends Iterator[Int] {
  private var current = 0
  override def hasNext: Boolean = current < to
  override def next(): Int =  {
    if (hasNext) {
      val t = current
      current += 1
      t
    } else 0
  }
}
 
 
val iterator = new IntIterator(10)
iterator.next()  //returns 0
iterator.next()  //returns 1

  此类IntIterator将参数to作为上限。extends Iterator[Int]意味着该next方法必须返回一个Int。

 

  • 分型

      在需要给定特征的情况下,可以使用特征的子类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import scala.collection.mutable.ArrayBuffer
 
trait Pet {
  val name: String
}
 
class Cat(val name: String) extends Pet
class Dog(val name: String) extends Pet
 
val dog = new Dog(name="Harry")
val cat = new Cat(name="Sally")
 
val animals = ArrayBuffer.empty[Pet]
animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name))

  trait Pet有一个抽象字段name,由Cat和Dog在其构造函数中实现。在最后一行,我们调用pet.name哪个必须在特征的任何子类型中实现Pet

 

2、正则表达式

       正则表达式是可用于在数据中查找模式(或缺少模式)的字符串。可以使用该.r方法将任何字符串转换为正则表达式

1
2
3
4
5
6
7
8
import scala.util.matching.Regex
 
val numberPattern: Regex = "[0-9]".r
 
numberPattern.findFirstMatchIn("awesomepassword11") match {
  case Some(_) => println("Password OK")
  case None => println("Password must contain a number")
}

  结果如下:

在上面的例子中,numberPattern是一个Regex (正则表达式),用它来确保密码包含一个数字。

 

3、提取器对象

    提取器对象是具有unapply方法 的对象,虽然apply方法就像一个构造函数,接受参数并创建一个对象,但是unapply接受一个参数并试图回馈参数,通常用于模式匹配和部分功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import scala.util.Random
 
object CustomerID {
  def apply(name:String) = s"$name--${Random.nextLong}"
 
  def unapply( customerID:String): Option[String] ={
    val stringArray:Array[String]=customerID.split("--")
    if(stringArray.tail.nonEmpty) Some(stringArray.head) else None
  }
  def main(args: Array[String]): Unit = {
    val customer1ID = CustomerID("harry--aaaaaa--jurry")
    customer1ID match {
      case CustomerID(name) => println(name) 
      case _ => println("Could not extract a CustomerID")
    }
  }
}

  apply方法CustomerID从创建一个字符串name,unapply做反拿到name回来。当我们调用时CustomerID("harry--aaaaaa--jurry"),这是调用的简写语法CustomerID.apply("harry--aaaaaa--jurry")。当我们打电话时case CustomerID(name) => println(name),我们正在调用unapply方法。

 

posted @   ~~。  阅读(217)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示