【问题标题】:What does the tilde (~) mean in this Scala example?在这个 Scala 示例中,波浪号 (~) 是什么意思?
【发布时间】:2013-06-13 22:58:20
【问题描述】:

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 *)
    }
  }
}

【问题讨论】:

  • 此表示法源自解析器组合器。请参阅stackoverflow.com/questions/6818390/… 简而言之,您可以在脑海中将~ 替换为&,因此这样的结构看起来像一个模式(你知道,就像正则表达式中的一个模式)。您正在使用特定部分(与 ~'s 组合成实体结构)定义高级表示,然后解析器要么成功,要么根据您的方案获得结构,或者失败。例如,要匹配代数表达式,可以写类似Number ~ Operation ~ Number ...
  • @om-nom-nom 那么,你为什么在评论中回答?
  • @DanielC.Sobral 因为我不确定这个问题是关于技术实现(gzm0 已经解释过)还是关于语义的东西。
  • 其实是tilda swinton的操作符。

标签: scala anorm


【解决方案1】:

在您的示例中,~ 以两种不同的方式用于表示两种不同的事物。在第一部分你有

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进行绑定,这在第8.1节中被称为中缀操作模式 .10 的language specification

在示例的第二部分中,您有:

case id ~ name ~ latitude ~ longitude =>

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

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

【讨论】:

    【解决方案2】:

    在 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)
    }
    

    【讨论】:

    • 更一般地说,a whatever b 表示a.whatever(b)(除了一些关键字、原始运算符和您已经提到的左关联指示符)。
    猜你喜欢
    • 1970-01-01
    • 2011-09-22
    • 2017-01-28
    • 2015-06-24
    • 2016-11-16
    • 2017-12-03
    • 2013-03-06
    • 1970-01-01
    相关资源
    最近更新 更多