繁体   English   中英

如何定义参数类型别名

[英]How to define a parametric type alias

我尝试定义一个参数类型别名:

case class A
case class B
case class C

// We need an Int to load instances of A and B, and a String to load C
object Service {
  def loadA(i: Int) : A = ???
  def loadB(i: Int) : B = ???
  def loadC(s: String) : C = ???
}

trait Location[T] { def get : T}
class IntLocation(val i: Int)
class StringLocation(val s: String)

trait EntityLocation[E] extends Location[_]

// Aim : make the loader typesafe
// Problem : I need something like that : type EntityLocation[Composite] = IntLocation
object Family {
  trait EntityLoader[EntityT] extends (EntityLocation[EntityT] => EntityT)
  val ALoader = new EntityLoader[A] {def load[A](l: EntityLocation[A]) = Service.loadA(l.get)
}

我不确定您要在这里实现什么。 您能否解释一下如何在代码中使用这些类型? 假设只想在代码中使用IdLocationFileLocation类型,也许您想尝试一下

trait Location[T] { def get : T }
type IdLocation = Location[Id]
type FileLocation = Location[java.io.File]

似乎有些令人费解,所以我不确定我是否完全遵循您的目的。 您似乎进入了创建工厂,调用工厂方法等的许多工厂层。

在我看来,最终,您需要拥有一个val ALoader值,该值可用于从Location [Int]对象获取A的实例,因此我将val ALoader假设:

     // Not sure what you want this one, but let's assume that you need a wrapper class per your example.
     trait Location[P] { def get: P }
     class IntLocation(val i: Int) extends Location[Int]
     {
        override def get: Int = i
     }

     // P for parameter, O for output class.
     def loader[O, P](creator: P => O)(param: Location[P]) = { creator(param.get) }

     object Service
     {
        // A function somewhere, capable of taking your parameter and creating something else (in your example, an Int to an 'A')
        // here Int to String to make something concrete.
        // This could be any function, anywhere
        def loadA(someParam: Int) = someParam.toString
     }

     def main(args: Array[String])
     {
        val myStringLoader: Location[Int] => String = loader(Service.loadA)
        // Alternatively, you could have written `val myStringLoader = loader(Service.loadA)(_)`. Either the type or the underscore are needed to tell the compiler that you expect a function, not a value.

        // Some definition for you wrapper class
        val location3 = new Location[Int]{
           override def get: Int = 3
        }

        // ... or just a plain old instance of it.
        val otherLocation = new IntLocation(5)

        // This would 'load' the kind of thing you want using the method you specified.
        val myString = myStringLoader(location3)
        val myOtherString = myStringLoader(otherLocation)

        // This prints "3 - 5"
        print(myString + " - " + myOtherString)
     }

这似乎是一个很长的答案,但实际上行def loader[O, P](creator: P => O)(param: Location[P]) = { creator(param.get) }是总而言之,剩下的就是使它与您的样本尽可能相似,并提供一个可用于工作的主线。

当然,如果您确实不需要整数的位置包装器,这将更加简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM