请原谅任何错误的术语;我对Scala比较陌生。我会尽力澄清:)
我想设置一个函数[T&lt ;: Closeable,R],参数T *,function(T *)=> R,然后用T * varargs作为参数调用函数。这在代码中可能更清晰:
import java.io.Closeable
object Loans {
/**
* works fine, yay!
* Eg: using(new FileWriter(file)) { fw => ...use fw... }
*/
def using[T <: Closeable, R](c: T)(action: T => R): R = {
try {
action(c)
} finally {
if (null != c) c.close
}
}
/**
* Won't compile:
* type mismatch;
* found: closeables.type (with underlying type T*)
* required: T possible cause: missing arguments for method or constructor
*
* Intended usage is:
*
* usingva(new FileWriter(f), new OtherCloseable()) { ... }
*/
def usingva[T <: Closeable, R](closeables: T*)(action: (T*) => R): Unit = {
try {
action.apply(closeables)
} finally {
//...close everything...
}
}
}
不幸的是,usingva版本没有编译,我对如何最好地完成varargs贷款结构感到有些失望。
任何和所有建议都非常感谢,ty。
答案 0 :(得分:5)
你必须在参数后面放一个:_*
来告诉编译器这不是一个参数而是整个seq参数:
action(closeables :_*)
编辑评论中的第二个问题:对于您的具体问题,最好不要使用varargs,而将结果Seq
直接与部分函数结合使用:< / p>
def usingva[T <: Closeable, R](closeables: T*)(action: PartialFunction[Seq[T], R]): Unit = {
try {
action(closeables)
}
finally {
//...close everything...
}
}
然后可以这样使用:
usingva(new FileWriter(file), new FileWriter(file) {
case Seq(fw1,fw2) => ... // You can use fw1 and fw2 seperately here
}
遗憾的是,没有办法使这种类型安全(即检查参数的数量是否与编译时的函数匹配),除了为所有数量的参数创建using
函数,因为类型级别没有整数支持在斯卡拉。像元组一样的问题...这就是为什么实际上有类Tuple1
,Tuple2
,...,Tuple22
(是的......它们在22点停止)
答案 1 :(得分:1)
您需要将varargs转换为类型系统的Seq(Scala在内部执行的操作)。
action : Seq[T] => R