【问题标题】:Structured Type to match Class Constructor结构化类型以匹配类构造函数
【发布时间】:2013-08-26 11:15:37
【问题描述】:

是否可以在 scala 中创建结构化类型以匹配类构造函数(与类中的方法/函数定义相反)

要正常匹配一个类的方法调用,你可以这样做

type SomeType : {def someMethod:String}

这可以让你做一些像这样的方法

someMethod(a:SomeType) = {
    println(a.someMethod)
}

类似这样的东西是什么意思

type AnotherType: {.......}

这将适用于这样的事情

class UserId(val id:Long) extends AnyVal

所以你可以做这样的事情

anotherMethod(a:AnotherType,id:Long):AnotherType = {
    new a(id)
}

anotherMethod(UserId,3) // Will return an instance of UserId(3)

我相信使用 runtimeClass 和 getConstructors 使用清单是可能的,但是我想知道这是否可以更干净地使用(通过使用结构化类型之类的东西)

【问题讨论】:

  • 不,不可能。
  • 嗯,好的,谢谢,所以我想您只需要将反射与清单一起使用?

标签: scala reflection manifest duck-typing


【解决方案1】:

考虑使用您的类型伴生对象作为函数值,而不是反射或结构类型,

scala> case class UserId(val id: Long) extends AnyVal
defined class UserId

scala> def anotherMethod[T, U](ctor: T => U, t: T) = ctor(t)
anotherMethod: [T, U](ctor: T => U, t: T)U

scala> anotherMethod(UserId, 3L)
res0: UserId = UserId(3)

这适用于案例类,因为 Scala 编译器将自动为伴随对象提供 apply 方法,该方法调用类主构造函数,并且它还将安排伴随对象扩展适当的 FunctionN 特征。

如果由于某种原因,您的类型不能是案例类,您可以自己提供 apply 方法,

object UserId extends (Long => UserId) {
  def apply(l: Long) = new UserId(l)
}

或者您可以在调用站点使用函数文字,

anotherMethod(new UserId(_: Long), 3L)

【讨论】:

  • 谢谢,这很好用。谢天谢地,将我的 UserId 转换为案例类并没有破坏任何东西!
  • 这也可以解释我的方法不起作用,没有任何等效的伴随对象(从不知道案例类提供了默认的伴随对象)。新东西要学!
猜你喜欢
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 2018-05-04
相关资源
最近更新 更多