【问题标题】:Casting a Map[String,String] to a case class User(id, name) using implicit method使用隐式方法将 Map[String,String] 转换为案例类 User(id, name)
【发布时间】:2017-09-13 18:09:26
【问题描述】:

我已经看到了如何将Map[String,String](例如("id"->"1", "name"->"andre"))转换为案例类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]。它说它不能将值转换为 User - 我也试过 .to[User] 并说

错误:(73, 24) 用户不接受类型参数,预期:一个 val r = u.get.to[用户]

完整代码:

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

}

【问题讨论】:

  • 您不应该使用强制转换 (.to[User]) - 只需将 r 的类型明确定义为 User 并且隐式转换将能够转换 u.get(我假设是一个Map[String, String]) 变成User: val r: User = u.get
  • 解决了,你愿意提交这个作为答案吗?

标签: scala implicit-conversion


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2015-10-16
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    相关资源
    最近更新 更多