我想编写一个case类,它可以接受一个或多个Ints作为参数的函数。例如,这些将是有效的功能:
def foo(x: Int): String = "foo"
def bar(x: Int, y: Int): String = "bar"
def foobar(x: Int, y: Int, z: Int): String = "foobar"
但这不会:
def nonExample():String = "no"
问题在于我无法为我的案例类获得正确的参数类型。
case class Mine(function: ???) {}
我试过了:
case class Mine(function: (Int*) => String)
这并没有奏效,因为(Int*
)是Ints
的序列。我也尝试使用Function和Function1,但这也没有用。任何想法(或者如果在Scala中不可能的替代方案)?
编辑: 正如Didier Dupont所提到的,Mine
还需要知道该方法需要多少个参数。上面我过度简化了Mine
。它还将采用另一个参数来说明传入的函数。基于此,它将决定传递给函数的参数数量。但除了那段代码之外,Mine
中的其他所有内容都是相同的,无论函数如何。
答案 0 :(得分:3)
我会推荐下一个解决方案(它有一些缺点,但通常它可以满足您的需求)
sealed trait FuncRes[F] {
def resolve : F
}
object FuncRes {
implicit def func1[T1, R](f : T1 => R) =
new FuncRes[(T1 => R)] {
def resolve = f
}
implicit def func2[T1, T2, R](f : (T1, T2) => R) =
new FuncRes[((T1, T2) => R)] {
def resolve = f
}
implicit def func3[T1, T2, T3, R](f : (T1, T2, T3) => R) =
new FuncRes[((T1, T2, T3) => R)] {
def resolve = f
}
}
case class Mine[F](private val f : FuncRes[F]) {
def func[F] = f.resolve
}
和用法示例:
def foo(x: Int): String = "foo"
def bar(x: Int, y: Int): String = "bar"
def foobar(x: Int, y: Int, z: Int): String = "foobar"
val m1 = Mine(foo _)
println { m1.func(10) } // output: "foo"
val m2 = Mine(bar _)
println { m2.func(10, 20) } // output: "bar"
val m3 = Mine(foobar _)
println { m3.func(10, 20, 30) } // output: "foobar"
答案 1 :(得分:0)
(Int, Int*) => String
怎么样?您将收到第二个参数Seq[Int]
。
答案 2 :(得分:-1)
为什么不使用函数Array[Int] => String
? Varargs本质上是阵列所以它应该适合。