使用隐式方法将 Map[String,String] 转换为 case class User(id, name)

Casting a Map[String,String] to a case class User(id, name) using implicit method

我看过如何将 Map[String,String](例如 ("id"->"1", "name"->"andre"))转换为案例 class User(id:String,name:String) 的示例,但它们涉及调用方法mapToUser - 例如:

val r = User.mapToUser(u.get)
      println("information for " + r.name + " with id " + r.id)

case class User(id: String, name: String)

object User {
  implicit def userToMap(user: User): Map[String, String] = {
    Map("id" -> user.id, "name" -> user.name)
  }

  implicit def mapToUser(m: Map[String, String]) : User = {
    User(m.get("id").get, m.get("name").get)
  }

  def unapply(arg: Map[String,String]): User = User(arg.get("id").get, arg.get("name").get)
}

Scala 非常了解如何使用 UserMap[String,String] 的第一个隐式转换,我不必调用 userToMap 但不明白为什么它会失败例如转换 var r = u.get.asInstanceOf[User]。它说它不能将值转换为用户 - 我也试过 .to[User] 并且说

Error:(73, 24) User takes no type parameters, expected: one val r = u.get.to[User]

完整代码:

import scredis._

import scala.concurrent.Future
import scala.util.{Failure, Success}

case class User(id: String, name: String)

object User {
  implicit def userToMap(user: User): Map[String, String] = {
    Map("id" -> user.id, "name" -> user.name)
  }

  implicit def mapToUser(m: Map[String, String]) : User = {
    User(m.get("id").get, m.get("name").get)
  }

  def unapply(arg: Map[String,String]): User = User(arg.get("id").get, arg.get("name").get)
}

object RedisClient {

  val redis = new Redis(host="192.168.122.2", passwordOpt = Some("privatemachine"))

  import redis.dispatcher

  def save(key:String, x : User) : Unit = {
    x.foreach {
      f => redis.hSet(key, f._1, f._2).onComplete{
        case Success(content) => None
        case Failure(e) => e.printStackTrace()
      }
    }
  }

  def get(key:String) : Future[Option[Map[String,String]]] = {
    val result = redis.hGetAll(key)

    result.onComplete {
      case Success(content) => {
        println(" --> " + content)
      }
      case Failure(e) => e.printStackTrace()
    }

    result
  }
}

object Run extends App {

  val redis = new Redis(host="192.168.122.2", passwordOpt = Some("privatemachine"))

  import redis.dispatcher


  redis.hSet("my-hash", "maker", "BMW")

  redis.hGetAll("my-hash") onComplete {
      case Success(content) => {
        println(content)
      }
      case Failure(e) => e.printStackTrace()
  }

  val u1 = User("1", "andre")
  RedisClient.save("user_1", u1)

  val userResult = RedisClient.get("user_1")
  userResult.map {
    u =>
      //val r = User.mapToUser(u.get)
      val r = u.get.to[User]
      println("information for " + r.name + " with id " + r.id)
  }.onFailure{ case x => println("Look here : " + x )}

}

您不必显式调用任何隐式方法,也不应使用转换。隐式转换可以简单地通过尝试将一种类型的实例分配给给定匹配转换的另一种类型的 variable/value 来应用。

因此在您的情况下,使用这些转换将按如下方式完成:

val map = Map("id" -> "1", "name" -> "2")
val u: User = map // implicit conversion into User
val m: Map[String, String] = u // implicit conversion back into Map