0Pricing
Scala for Backend Engineering & Functional Programming · 课时

匹配类型与值

类型模式

匹配类型与值 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Type Patterns

Beyond matching literal values, match can branch on the type of a value. This is called a type pattern.

You write case x: Type => and the branch runs when the value is of that type, binding it to x.

Matching by Type

When a value has a general type like Any, you can discover its concrete type with a type pattern.

Each case x: T checks the runtime type.

object Main {
  def describe(x: Any): String = x match {
    case i: Int    => "an Int"
    case s: String => "a String"
    case _         => "something else"
  }
  def main(args: Array[String]): Unit = {
    println(describe(5))
    println(describe("hi"))
    println(describe(3.14))
  }
}

Using the Bound Value

The bound name has the matched type, so you can call its methods safely in that branch.

No casting needed: the compiler knows the type inside the case.

object Main {
  def shout(x: Any): String = x match {
    case s: String => s.toUpperCase
    case i: Int    => (i * 2).toString
    case _         => "?"
  }
  def main(args: Array[String]): Unit = {
    println(shout("hello"))
    println(shout(21))
  }
}

Type and Value Together

You can mix value patterns and type patterns in the same match. Value patterns are usually more specific, so place them first.

object Main {
  def check(x: Any): String = x match {
    case 0       => "zero int"
    case i: Int  => s"nonzero int $i"
    case _       => "not an int"
  }
  def main(args: Array[String]): Unit = {
    println(check(0))
    println(check(7))
    println(check("x"))
  }
}

Matching Double and Boolean

Type patterns work for any type, including Double, Boolean, and Char.

object Main {
  def kind(x: Any): String = x match {
    case d: Double  => s"double $d"
    case b: Boolean => s"bool $b"
    case _          => "other"
  }
  def main(args: Array[String]): Unit = {
    println(kind(2.5))
    println(kind(true))
  }
}

Matching Collections by Type

You can also match container types like List. Here we distinguish a list from other values.

object Main {
  def info(x: Any): String = x match {
    case l: List[_] => s"a list of size ${l.size}"
    case _          => "not a list"
  }
  def main(args: Array[String]): Unit = {
    println(info(List(1, 2, 3)))
    println(info("nope"))
  }
}

A Common Use: Handling Any

Type patterns shine when a function receives Any and must react differently per type, such as logging or serialization.

object Main {
  def render(x: Any): String = x match {
    case i: Int    => s"int=$i"
    case d: Double => s"dbl=$d"
    case s: String => s"str=$s"
    case _         => "unknown"
  }
  def main(args: Array[String]): Unit = {
    List(1, 2.0, "three").foreach(v => println(render(v)))
  }
}

Order Still Matters

Like all matches, type patterns are checked top to bottom. A broader type placed first can hide a narrower one below.

Always order from most specific to most general.

object Main {
  def label(x: Any): String = x match {
    case s: String => "string first"
    case _: Any    => "anything"
  }
  def main(args: Array[String]): Unit = {
    println(label("hi"))
    println(label(99))
  }
}

Type Erasure Caveat

At runtime, generic type parameters are erased. So List[Int] and List[String] look the same. Matching on List[Int] only checks that it is a List.

Use List[_] to be explicit and avoid warnings.

Why Type Patterns?

Type patterns let you:

  • Safely narrow a general type without casting
  • Handle heterogeneous values cleanly
  • Combine with value patterns and guards

They are a stepping stone to matching on case classes and ADTs.

Putting It Together

Combine value and type patterns to classify mixed input.

object Main {
  def classify(x: Any): String = x match {
    case 0          => "zero"
    case i: Int     => "int"
    case s: String  => "text of length " + s.length
    case _          => "other"
  }
  def main(args: Array[String]): Unit = {
    println(classify(0))
    println(classify(5))
    println(classify("hey"))
  }
}

Quick Check

Test your knowledge of type patterns.

Recap

You learned to match on types:

  • case x: Type matches by runtime type and binds x
  • The bound value has the matched type, so no cast is needed
  • Mix value and type patterns, most specific first
  • Generic parameters are erased, so use List[_]

常见问题解答

「匹配类型与值」课时是免费的吗?

是的 — 「匹配类型与值」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

「匹配类型与值」这节课中我会学到什么?

类型模式 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「匹配类型与值」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. match 表达式
  2. 匹配类型与值
  3. 守卫与绑定
  4. 解构
← 返回 Scala for Backend Engineering & Functional Programming