Scala集合、Option类型与XML处理
立即解锁
发布时间: 2025-08-24 01:22:42 阅读量: 1 订阅数: 3 

### Scala 集合、Option 类型与 XML 处理
#### 1. Option[T] 类型概述
Option[T] 为给定类型的零个或一个元素提供容器,是 Java 中 null 的强大替代方案。Option[T] 可以是 Some[T] 或 None,其中 None 是一个对象,在 Scala 程序中只有一个实例,类似于 null,但它有方法,无论处理的是 Some 还是 None,都可以调用 map、flatMap、filter、foreach 等方法。
例如,有一个根据主键从数据库中检索记录的方法:
```scala
def findPerson(key: Int): Option[Person]
```
若找到记录,该方法返回 Some[Person];若未找到,则返回 None。在此基础上,可以构建一个根据主键返回年龄的方法:
```scala
def ageFromKey(key: Int): Option[Int] = findPerson(key).map(_.age)
```
若数据库中找到记录,ageFromKey 将返回 Some[Int];否则返回 None。可以对 Option 进行级联映射/扁平化映射,而无需显式测试是否为 None。
以下是一些辅助方法的定义:
```scala
import java.lang.{Boolean => JBool}
def tryo[T](f: => T): Option[T] = try {Some(f)} catch {case _ => None}
def toInt(s: String): Option[Int] = tryo(s.toInt)
def toBool(s: String) = tryo(JBool.parseBoolean(s))
```
这些方法用于将操作封装在 try/catch 块中,若操作成功,将结果封装在 Some 实例中;否则返回 None。利用这些辅助方法,可以定义将参数转换为 Person 实例的方法:
```scala
def personFromParams(p: Map[String, String]): Option[Person] =
for {name <- p.get("name")
ageStr <- p.get("age")
age <- toInt(ageStr)
validStr <- p.get("valid")
valid <- toBool(validStr)}
yield new Person(name, age, valid)
```
与 Java 实现相比,Java 代码需要显式测试每个键,增加了代码行数,降低了可读性,且有多个返回路径,难以理解代码在何种条件下继续执行,也难以确定方法返回非 null 的条件。
Option 还有一些允许链式调用的方法,如 orElse。若映射到 “age” 的参数名以前叫 “years”,可以这样表达代码:
```scala
ageStr <- p.get("age") orElse p.get("years")
```
若 p.get("age") 返回 None,则会调用 p.get("years")。
可以使用 get 方法检索 Option 的内容,但要注意,若 Option 为 None,会抛出异常:
```scala
scala> Some(3).get
res57: Int = 3
scala> None.get
java.util.NoSuchElementException: None.get
```
Option 还有 getOrElse 方法,若内容未定义,则返回默认值:
```scala
scala> Some(3).getOrElse(44)
res59: Int = 3
scala> None.getOrElse(44)
res60: Int = 44
```
Option 是一个非常有用的类,可用于传递或返回可能未定义的值。由于它有 map、flatMap、filter 和 foreach 方法,可用于 for 推导式,能有效避免 null 问题,且其方法与其他 Scala 集合配合使用很方便。
#### 2. XML 的创建与操作
Scala 在语言层面支持定义 XML 常量,Scala 中的 XML 是不可变的,就像 Java 中的 String 一样,这意味着可以缓存 XML,而不用担心它被意外修改。
##### 2.1 XML 的创建
Scala 语言语法中内置了 XML 字面量,就像 Java 内置了 String 字面量一样。可以直接编写 XML 代码:
```scala
scala> <b>Hello World</b>
res0: scala.xml.Elem = <b>Hello World</b>
```
可以包含属性:
```scala
scala> <b id="greeting">Hello World</b>
res1: scala.xml.Elem = <b id="greeting">Hello World</b>
```
XML 可以跨多行:
```scala
scala> <b id="greeting">
<span>Hello</span> World!
</b>
res2: scala.xml.Elem =
<b id="greeting">
<span>Hello</span> World!
</b>
```
XML 元素可以包含前缀,属性也可以有前缀:
```scala
scala> <ns:b>Hello World from a namespace</ns:b>
res0: scala.xml.Elem = <ns:b>Hello World from a namespace</ns:b>
scala> <b ns:hi='hello'>Hello</b>
res12: scala.xml.Elem = <b ns:hi="hello">Hello</b>
```
可以将 XML 赋值给变量:
```scala
scala> val x = <b>Hello World!</b>
x: scala.xml.Elem = <b>Hello World!</b>
```
Scala 将 XML 表示为 Seq[Node],Node 是 NodeSeq 的超类,NodeSeq 是 Seq[Node] 的子类,这意味着之前探索的所有集合方法(如 map、flatMap、filter 和 foreach)都可用于 XML 集合,XML 也可用于 for 推导式。
可以定义一个计算 Seq 长度的方法:
```scala
scala> def len(seq: Seq[_]) = seq.length
len: (Seq[_])Int
```
并使用 XML 字面量、之前定义的 XML 变量或 List[Int] 调用该方法:
```scala
scala> len(<b>Hello</b>)
res1: Int = 1
scala> len(x)
res2: Int = 1
scala> len(List(1,2,3))
res11: Int = 3
```
Scala 动态创建 XML 的能力比动态创建 String 强大得多,可以在任何属性或元素体中嵌入 Scala 代码来动态渲染 XML。例如,定义一个返回当前毫秒数的方法:
```scala
scala> def now = System.currentTimeMillis.toString
now: java.lang.Str
```
0
0
复制全文
相关推荐








