scala – 给定方法参数返回最具体的类型
我试图在给定一些变量参数的情况下创建一个特定且唯一的类型.
下面列出了代表前四个自然数的预定义类型(使用类似于Digit0..Digit9,DimensionCons和EndDimension(如HNil)的HList). object Defined { type D1 = DimensionCons[Digit1,EndDimension.type] val d1 = DimensionCons(Digit1(),EndDimension) type D2 = DimensionCons[Digit2,EndDimension.type] val d2 = DimensionCons(Digit2(),EndDimension) type D3 = DimensionCons[Digit3,EndDimension.type] val d3 = DimensionCons(Digit3(),EndDimension) type D4 = DimensionCons[Digit4,EndDimension.type] val d4 = DimensionCons(Digit4(),EndDimension) } 我正在寻找一种带有指示签名的方法 def getDimensionTpe[D <: Dimension](dim: Int) : D 例如返回getDimensionTpe(2)的DimensionCons [Digit2,EndDimension.type]. 问题: >这是否可能没有whitebox宏(生成类型?)如果是这样,如何以及如何处理? 谢谢,马丁 解决方法
我不确定我是否理解你在DimensionCons和DigitN业务中究竟做了什么,但是可以使用Shapeless编写一个采用整数的方法(尽管只有一个文字常量 – 必须在编译时知道 – 时间)并使该整数确定返回值的静态类型.
为了简化代码以获得完整的工作示例,假设我们要编写如下方法: trait Dimension case class Dim1() extends Dimension case class Dim2() extends Dimension case class Dim3() extends Dimension // And so on... def getDimensionTpe[D <: Dimension](dim: Int) : D …其中getDimensionTpe(1)将返回Dim1()(静态类型为Dim1),getDimensionTpe(2)将返回Dim2()等.为此,我们可以在无形自然数和维度之间引入类型类映射: import shapeless.{ DepFn0,Nat } trait DimMap[N <: Nat] extends DepFn0 { type Out <: Dimension } object DimMap { type Aux[N <: Nat,D <: Dimension] = DimMap[N] { type Out = D } implicit val dimMap1: Aux[Nat._1,Dim1] = new DimMap[Nat._1] { type Out = Dim1 def apply(): Dim1 = Dim1() } implicit val dimMap2: Aux[Nat._2,Dim2] = new DimMap[Nat._2] { type Out = Dim2 def apply(): Dim2 = Dim2() } implicit val dimMap3: Aux[Nat._3,Dim3] = new DimMap[Nat._3] { type Out = Dim3 def apply(): Dim3 = Dim3() } // And so on as needed. } 如果您的维度类型有更多结构,则可以在此处避免使用样板,但我不清楚您的DigitN内容是如何工作的.然而,这似乎与问题的主要方面正交,关于如何定义getDimensionTpe. 如果你不介意写一个白盒宏,你可以将它定义为具有非常类似下面的签名的东西: def getDimensionTpe[D <: Dimension](dim: Int) : D 尽管如此,这对于屁股来说是一个巨大的痛苦,而Shapeless可以让你在没有自定义宏的情况下编写基本相同的东西.给定上面的DimMap类型,您可以编写以下内容: def getDimensionTpe(dim: Nat)(implicit m: DimMap[dim.N]) : m.Out = m() 然后: scala> val d1: Dim1 = getDimensionTpe(1) d1: Dim1 = Dim1() scala> val d2: Dim2 = getDimensionTpe(2) d2: Dim2 = Dim2() scala> val d3: Dim3 = getDimensionTpe(3) d3: Dim3 = Dim3() 如果你得到的静态类型错误,编译器会告诉你: scala> val d3: Dim1 = getDimensionTpe(3) <console>:15: error: type mismatch; found : DimMap.dimMap3.Out (which expands to) Dim3 required: Dim1 val d3: Dim1 = getDimensionTpe(3) ^ 如果提供没有映射的整数文字,那也是编译时错误: scala> getDimensionTpe(0) <console>:14: error: could not find implicit value for parameter m: DimMap[shapeless._0] getDimensionTpe(0) ^ 最后,如果您提供的Int参数不是整数文字,您还会收到编译器错误: scala> val x = 1 x: Int = 1 scala> getDimensionTpe(x) <console>:16: error: Expression x does not evaluate to a non-negative Int literal getDimensionTpe(x) ^ 在幕后,Shapeless正在使用一个宏来实现这一点,甚至不是那么可怕 – 你可以阅读the (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |