1

Scala初学者,在这里。老实说,我对整个表达方式感到很困惑。我隐约明白这是做什么的,但是~s在做什么呢?

val simple = {
   get[String]("user.email") ~
   get[String]("user.name") ~
   get[String]("user.password") map {
     case email~name~password => User(email, name, password)
   }
}

如果您好奇或需要更多信息,这里是github 源代码。

提前致谢!

4

2 回答 2

1

是的,该方法RowParser.~将两个单独的 RowParsers 组合为单独的列,给出结果 RowParser[anorm.~[Col1Type, Col2Type]]。以下是处理细节:

  1. Singletonobject anorm.SqlParser已导入所有成员。

  2. 它有一个方法get[T]

    def get[T](columnName: String)(implicit extractor: Column[T]): RowParser[T] 
    
    • 调用时,泛型参数T被实例化为String
    • 输入参数columnName填充为"user.email"
    • 输入参数extractorimplicit。它不在调用中提供。Column因此,编译器使用单例对象中的类型签名匹配来获取一个隐式值。它找到了方法rowToString: Column[String]
    • 输出参数RowParser[T]被实例化RowParser[String]
  3. anorm.RowParser[String]调用了方法“ ~”。它的签名是:

    def ~[B](p: RowParser[B]): RowParser[~[String, B]]  
    
  4. 但是“ ~”的输入(参数 p)是什么?它在下一行:get[String]("user.name") ~.

  5. 由于方法调用的这种“链接”,方法调用顺序实际上是自下而上的:

    • 第一的

      get[String]("user.password") map {
        case email~name~password => User(email, name, password)
      

      返回类型RowParser[String]

    • 它被传递到

      get[String]("user.name") ~
      

      返回类型RowParser[~[String, String]]。在这里,它使用了不同的“~”——定义为案例类的类型: anorm.~[A,B]

      case class ~[+A, +B](_1: A, _2: B) extends Product with Serializable 
      

      表示合并行中两个已解析列的结果。

    • 此 RowParser 被传递到:

      get[String]("user.email") ~
      

      返回类型RowParser[~[String, RowParser[~[String, String]]]]

于 2013-10-25T07:04:40.307 回答
0

弄清楚了。'~' 是对一行进行操作的解析器组合器。它验证 user.emal、user.name、user.password 的存在,其结果(如果成功)是可以映射的 ~[A, B, C]。在这种情况下,如果所有 3 个都存在,则创建并返回一个新的 User 对象。

于 2013-10-24T03:39:29.293 回答