2

我正在开发一个简单的函数,它应该基于可能不存在的可选参数构建一个 sql 条件。

我正在尝试使用不可变值以及优雅和惯用的方式来完成它。

到目前为止,我带来了这样的东西:

val cond: Seq[String] = Nil ++ 
  (if (entity != "*") Seq("entity = {entity}") else Nil) ++
  (if (name != "*") Seq("name = {name}") else Nil) ++

val condition = 
  if (cond.size == 0) "" 
  else " where " + cond.mkString(" and ") + " "

所以,我只是合并 Seqs,如果该值不存在,我将它与 Nil 合并

使用 var 我得到类似的东西:

var cond: Seq[String] = Seq();
if (entity != "*") cond = cond :+ "entity = {entity}"
if (name != "*") cond = cond :+ "name = {name}"

我发现它更具可读性(我想知道第二种方法是否因为 var 而不是线程安全的)

我想知道解决此类问题的 scala 惯用且优雅的方法是什么

- 编辑

最后,我确定了这个实现:

val condition: String = {

  var cond: Seq[String] = Seq();

  if (entity != "") 
    cond = cond :+ "entity = {entity}"
  if (filter != "")
    cond = cond :+ """(name like {filter} or prev like {filter} or post like {filter})"""

  if (cond.size == 0) "" 
  else " where " + cond.mkString(" and ") + " "
}
4

2 回答 2

5

不要重复自己:

def seqIf(r: String, s: String) = if (r != "*") Seq("%s = {%s}".format(s,s)) else Nil

val cond = seqIf(entity, "entity") ++ seqIf(name, "name")

不仅是字符串:

def seqIf[A](p: Boolean, a: A) = if (p) Seq(a) else Nil

val cond = seqIf(entity != "*", "entity = {entity}") ++ 
  seqIf(name != "*", "name = {name}")
于 2012-05-31T03:37:12.010 回答
4

另一种方法是保留可变结构,但隐藏在块中以避免副作用:

val cond = {
  var cs = Seq[String]()
  if (entity != "*") cs = cs :+ "entity = {entity}"
  if (name != "*") cs = cs :+ "name = {name}"
  cs
}

这样的构造是完全安全的,因为var在块外无法访问。您还可以将 val 与可变构建器一起使用,例如ListBuffer. 在这种情况下。只要确保您没有将可变对象泄漏到块外:

import scala.collection.mutable.ListBuffer

val cond = {
  val cs = ListBuffer[String]()
  if (entity != "*") cs += "entity = {entity}"
  if (name != "*") cs += "name = {name}"
  cs.result() //Converts the ListBuffer into an immutable List
}

这是完全可以接受的,因为块本身仍然是“纯的”。这种模式出现在 Scala API 中。

于 2012-05-31T07:12:31.663 回答