Scala - 在模式匹配中指定匹配项

时间:2012-03-10 08:33:53

标签: scala binding pattern-matching

我有以下代码:

class Animal(hair: Option[Hair])

class Cat(var hair: Option[Hair]) extends Animal(hair)
class Dog(var hair: Option[Hair]) extends Animal(hair)
class Sheep(var hair: Option[Hair]) extends Animal(hair)

//then somewhere else:

def what(animal: Animal) {

  animal match {
    case Cat(hair) => println("processing cat, hair=" + hair)
    case Dog(hair) => println("processing dog, hair=" + hair)
    case Sheep(hair) => {
      println("processing sheep, cutting hair...")
      hair = None
    }
  }
}

问题是:

1)当模式匹配与绵羊成功时,我怎样才能进入它的头发并改变它?它抱怨重新分配到val,然后我将var放在构造函数中但仍然......

2)我能想到的另一种方法是将整个匹配值分配给变量,有没有办法将一些case类构造函数模式匹配的值绑定到变量?

(我知道我可能会对s: Sheep之类的内容进行匹配,然后调用s.changeHairTo(None),但这是最不可取的方式。)

2 个答案:

答案 0 :(得分:25)

您可以使用@将整个模式绑定到版本中的变量

class Animal(hair: Option[Hair])
case class Cat(var hair: Option[Hair]) extends Animal(hair)
case class Dog(var hair: Option[Hair]) extends Animal(hair)
case class Sheep(var hair: Option[Hair]) extends Animal(hair)

def what(animal: Animal) {
  animal match {
    case Cat(hair) => println("processing cat, hair=" + hair)
    case Dog(hair) => println("processing dog, hair=" + hair)
    case s @ Sheep(hair) => {
      println("processing sheep, cutting hair...")
      //cut(hair)
      s.hair = None
    }
  }
}

但您不必使用var。这是您的代码段的更多功能版本。 what此处只需在切割后Sheep None返回Hair

trait Animal
case class Cat(hair: Option[Hair]) extends Animal
case class Dog(hair: Option[Hair]) extends Animal
case class Sheep(hair: Option[Hair]) extends Animal

def what(animal: Animal): Animal =
  animal match {
    case Cat(hair) =>
      println("processing cat, hair=" + hair)
      animal
    case Dog(hair) =>
      println("processing dog, hair=" + hair)
      animal
    case Sheep(hair) => {
      println("processing sheep, cutting hair...")
      //cut(hair)
      Sheep(None)
    }
  }

答案 1 :(得分:4)

这不起作用,因为在模式匹配中,var“hair”只是从Sheep对象中提取的,因此它不是Sheep的字段,而是case块上下文中的变量。你可以这样做:

class Hair

trait Animal {
  var hair: Option[Hair]
}
case class Cat(var hair: Option[Hair]) extends Animal
case class Dog(var hair: Option[Hair]) extends Animal
case class Sheep(var hair: Option[Hair]) extends Animal

//then somewhere else:

def what(animal: Animal) {

  animal match {
    case Cat(hair) => println("processing cat, hair=" + hair)
    case Dog(hair) => println("processing dog, hair=" + hair)
    case Sheep(hair) => {
      println("processing sheep, cutting hair...")
      animal.hair = None
    }
  }
}

告诉Animal它有一个可变的领域头发,您可以设置它而不将其转换为正确的类型。