Scala中的隐式转换

Scala中的隐式转换,scala,type-conversion,Scala,Type Conversion,是否可以进行duck类型转换,其中转换器将接受任意对象并尝试将其转换为目标类型 case class RequiredFields(name: String, surname: String) case class Person(name: String, surname: String, age: Option[Int]) implicit def arbitraryToPerson(object: ????): Person = Person(object.name, object.surn

是否可以进行duck类型转换,其中转换器将接受任意对象并尝试将其转换为目标类型

case class RequiredFields(name: String, surname: String)
case class Person(name: String, surname: String, age: Option[Int])
implicit def arbitraryToPerson(object: ????): Person = Person(object.name, object.surname, None)

任意对象不必以任何方式与RequiredField类相关,只要字段必须存在。

我认为您正在寻找一个特征:

trait Nameable {
  def name: String
  def surname: String
}
case class Person(name: String, surname: String, age: Option[Int]) extends Nameable
implicit def arbitraryToPerson(variable: Nameable): Person = Person(variable.name, variable.surname, None)
你可以把一个特性想象成一个界面。Scala特性的一个特点是,它们也接受其方法的实现

扩展此特性的类将需要实现方法
name
lasname
。在这种情况下,唯一有效的可命名参数是Person。拥有更多的类来扩展这个特性将允许某种形式的多态性,这使得这个隐式方法实际上很有用

编辑 从你的评论和否定中,我只想指出,你可以随心所欲地称呼自己的特质。在您的情况下,类似于
Nameable
的功能可能会起作用。这并不意味着存在层次结构,而是意味着对象满足某些条件,比如实现那些方法。类可以使用
with
关键字扩展Scala中的多个特征

case class Dog(name: String, surname: String) extends Animal with Nameable

在这种情况下,您的狗可能是一种动物,但您可以通过扩展特征来强制实施命名方法。

正如hasumedic回答的,您可能想要使用特征

如果出于某种原因,您不想使用trait(您无法控制发送给您的包对象等),您也可以使用反射来获取字段。(我不知道这是否是个好主意,但我最好的猜测是不是)

然后,通过调用scala为您创建的字段的getter来获得您的值

scala> val x = method.invoke(rF).asInstanceOf[String]
x: String = Hey

我认为可以将结构类型和隐式转换结合起来。像这样:

type RequiredFields = { 
  def name: String
  def surname: String
}

case class NotAPerson(name: String, surname: String)
case class Person(name: String, surname: String, age: Option[Int])

implicit def arbitraryToPerson(o: RequiredFields): Person = Person(o.name, o.surname, None)

val p:Person = NotAPerson("oh", "my")

你确定这是个好主意吗?我认为这里更好的模式是用必需的字段定义一个类型类。您是否考虑过这一点?

您似乎可以通过以下方式进行类型驱动转换:

implicit def convertToPerson(obj: {def name(value: String): String; def surname(): String}): Person = {
    Person(obj.name, obj.surname, None)
}

不是真的,我不想有类层次结构。我有一个任意的对象,它可能是person的超类,也可能不是。例如,转换将适用于所有具有字段的对象,而不管它们的继承情况如何。@ArtursVacans然后,您需要为要用作创建Person的数据源的任何类型更改类型Human。从那一刻起,您将能够将该类型发送给Person类型的参数。我认为这会起作用,但我并不想用额外的特性污染我的目标实体:/n您可以,但正如Lutz观察到的,您不应该。至少,我希望没有人会求助于这个,除非是在非常不寻常的情况下。
implicit def convertToPerson(obj: {def name(value: String): String; def surname(): String}): Person = {
    Person(obj.name, obj.surname, None)
}