使用Slick重构期间键入不匹配

时间:2016-04-21 21:10:56

标签: scala slick

我有以下一段代码我想制作DRYer:

def createAdmin(/* ... */): Future[Int] =
  db.run {
    {
      (users returning users.map(_.id)) += Account(0, /* ... */)
    } flatMap { id =>
      admins += Admin(userId = id, /* ... */)
    }
  }

def createStandardUser(/* ... */): Future[Int] =
  db.run {
    {
      (users returning users.map(_.id)) += Account(0, /* ... */)
    } flatMap { id =>
      standardUsers += StandardUser(userId = id, /* ... */)
    }
  }

编译好。但如果我将两者合并到以下内容中:

def createUser(role: String)(/* ... */): Future[Int] =
  db.run {
    {
      (users returning users.map(_.id)) += Account(0, /* ... */)
    } flatMap { id =>
      role match {
        case "admin" =>
          admins += Admin(userId = id, /* ... */)
        case "standard" =>
          standardUsers += StandardUser(userId = id, /* ... */)
      }
    }
  }

我收到以下类型不匹配错误:

[error]  found   : Long => slick.dbio.DBIOAction[Int,slick.dbio.NoStream,Nothing]
[error]  required: Long => slick.dbio.DBIOAction[Int,slick.dbio.NoStream,E2]
[error]       } flatMap { id =>
[error]                      ^
[error] one error found

我似乎无法弄明白为什么。有人可以为我阐明这个吗?

2 个答案:

答案 0 :(得分:6)

编译器无法正确找出使用过的效果类型。作为一种解决方法,您应该能够通过指定使用的类型为其提供一些帮助,例如:在flatMap操作中,这将是

flatMap[Int, NoStream, Effect.Write] { id => 

在你的情况下。

答案 1 :(得分:1)

我担心你无法以这种方式重构代码。 我知道从代码的角度看它看起来很合理。但是flatMap中的模式匹配没有为编译器提供足够的信息来推断effectDBIOAction

您可以阅读source code

  

撰写动作时,将推断出正确的组合效果类型

换句话说,由于Slick不知道在编译时第一次插入后你打算做什么,编译失败了。 as the documentation says,“为了更有效的执行,不可能融合这些行动”。