在这个Scala示例中,波浪号(〜)的含义是什么?

时间:2013-06-13 22:58:20

标签: scala anorm

http://woss.name/2012/04/02/retrieving-bigdecimals-from-a-database-with-anorm-scala/

object Site {
  val allFieldsParser = {
    get[Pk[Long]]("sites.id") ~     // Help me parse this syntax
    get[String]("sites.name") ~
    get[BigDecimal]("sites.latitude") ~
    get[BigDecimal]("sites.longitude") map {
      case id ~ name ~ latitude ~ longitude =>
        Site(id, name, latitude, longitude)
    }
  }

  def findAll(): Seq[Site] = {
    DB.withConnection { implicit connection =>
      SQL("SELECT * FROM sites").as(Site.allFieldsParser *)
    }
  }
}

2 个答案:

答案 0 :(得分:23)

在你的例子中,〜以两种不同的方式用于表示两种不同的东西。在第一部分你有

get[Pk[Long]]("sites.id") ~     // Help me parse this syntax
get[String]("sites.name") ~
get[BigDecimal]("sites.latitude") ~

等。正如已经指出的那样,这只是方法调用,它与

相同
get[Pk[Long]]("sites.id").~(get[String]("sites.name").~(...

您可以查看the definition of this method in the anorm source。它是RowParser[A]上的一种方法(一个解析A的解析器,它接受一个RowParser[B](一个解析B的解析器)并返回一个解析一个解析器的解析器A ~ B。此A ~ B~的第二个含义。现在不是指方法,而是指case class defined in the same file here.

case class ~[+A, +B](_1: A, _2: B)

这只是引用课程~[A,B]的一种特殊方式。在类型级别,当您有两个参数类型构造函数时,可以在中缀表示法中使用该类的名称。这与~没什么特别之处,它适用于任何两个参数类型构造函数。如果您有trait Foo[A,B],则可以将其称为A Foo B。类似地,在模式匹配中,变量ab可以使用语法a Foo b进行绑定,这被称为中缀操作模式< / em>在language specification的第8.1.10节中。

在你的例子的第二部分,你有:

case id ~ name ~ latitude ~ longitude =>

这是对这些~个案句的模式匹配,这是运行您在上面构建的解析的结果。所以这真的只是一种更好的写作方式:

case ~(~(~(id, name), latitude), longitude) =>

答案 1 :(得分:6)

在Scala中

a ~ b

装置

a.~(b)

因此它调用~上的方法a并将b作为参数。另请注意,任何不以:结尾的运算符都是左关联的。

重访的例子是:

get[Pk[Long]]("sites.id").~(     // Help me parse this syntax
get[String]("sites.name").~(
get[BigDecimal]("sites.latitude").~(
get[BigDecimal]("sites.longitude")))) map {
  case id ~ name ~ latitude ~ longitude =>
    Site(id, name, latitude, longitude)
}