我想编写一个泛型函数functionChooser
,它将根据String参数从几个选项中选择使用哪个函数。
这有效:
def a (arg: String) = arg + " with a"
def b (arg: String) = arg + " with b"
def c (arg: String) = arg + " with c"
def functionChooser(func: String, additionalArg: String) = {
val f = func match {
case "a" => a _
case "b" => b _
case _ => c _
}
f(additionalArg)
}
scala> functionChooser("a", "foo")
res18: String = foo with a
我在制作functionChooser
通用邮件方面遇到了麻烦,例如当函数a
,b
和c
返回不同的案例类时:
case class A(s: String)
case class B(s: String)
case class C(s: String)
def a (arg: String) = A(arg)
def b (arg: String) = B(arg)
def c (arg: String) = C(arg)
//functionChooser def as before
scala> functionChooser("a", "foo")
res19: Product with Serializable = A(foo)
我不太明白我到达那里的地方,我知道在致电functionChooser("a", "foo").s
(" error: value s is not a member of Product with Serializable
")时出现错误。
最后,我真正想要的是函数将返回这些案例类的列表,例如:
def a (arg: String) = List(A(arg))
def b (arg: String) = List(B(arg))
def c (arg: String) = List(C(arg))
所以functionChooser
应该是List[T]
的通用,其中T
是某个类。
答案 0 :(得分:4)
函数functionChooser
将返回案例类A
,B
和C
中最具体的常见超类型。由于案例类继承自Product
和Serializable
,因此常见的超类型为Product with Serializable
。
如果要访问案例类字段s
,您必须通过模式匹配来转换结果,或者提供所有类A
的公共基类,{{1} }和B
,允许您访问该字段。
C
使用此类型定义,trait Base {
def s: String
}
case class A(s: String) extends Base
case class B(s: String) extends Base
case class C(s: String) extends Base
的返回类型为functionChooser
,因此,结果将允许您访问Product with Serializable with Base
。
如果您的函数s
,a
和b
返回相应案例类的c
,那么List
的返回类型将是{{ 1}}。
如果您无法更改类层次结构,则必须转换结果,或者您可以在functionChooser
中提取必要的信息,并将其包含在另一种类型中,该类型包含您需要的所有数据的超级集合。 E.g。
List[Product with Serializable with Base]
注意:这里我只提取字段functionChooser
,它是所有必需信息的超级集合。
答案 1 :(得分:1)
您应该返回所有三个函数的上部公共类型。对象(AnyRef)始终适合。
def functionChooser(func: String, additionalArg: String) : AnyRef = {
在您的情况下,所有可能的返回值都是列表,您可以使用更具体的类型:
def functionChooser(func: String, additionalArg: String) : List[_] = {
当然,这将消除类型信息。任何方法都应该返回相同的类型,它不能是多态的。因此,您需要进一步使用.asInstanceOf[T]
案例,以获取此信息。
这是有道理的,因为实际类型在运行时是未知的。例如调度程序字符串可以由用户输入。如果在编译期间知道它,那么您可以使用适当的方法而不引用描述性字符串。
如果您希望获得所有可能返回类型的一些常见行为,那么您应该为它们定义一个共同特征并为其设置常用方法。