2011-03-08 28 views
1

请对照任何错误的术语;我对斯卡拉来说比较新。我会尽力澄清:)如何通过apply()将同变量可变参数传递给具有相同类型的同变量可变参数的函数

我想设置一个函数[T <:Closeable,R],使用参数T *,函数(T *)=> R,然后调用T *可变参数,因为它是参数。这可能是更清晰的代码:

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版本不编译,我在稍微亏损为如何最好地实现可变参数贷款结构。

任何和所有的建议非常感谢,ty。

回答

5

你将不得不把:_*在后面的参数来告诉编译器,这不是一个单一的说法,但参数的整个序列:

action(closeables :_*) 

编辑关于你的第二个问题在评论中:对于您的具体问题,可能不是使用可变参数,而是由直接结合部分函数:

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函数外,因为scala中的类型级别没有整数支持。像元组一样的问题...这就是为什么实际上有类Tuple1,Tuple2,...,Tuple22(是...他们停在22)

+0

OK; action(可关闭:_ *)和action.apply(可关闭:_ *)都可以编译。这可能是一个愚蠢的问题,但有没有办法将单个项目变为变量?也就是说,这是有效的:'usingva(new FileWriter(file),new FileWriter(file)){fw => ...}'但我更喜欢能够沿'usingva(new FileWriter (文件),新的FileWriter(文件)){fw1,fw2 => ...}。也就是说,为了让每个变量都可以在自己的变量中关闭,而不是使用FileWriter *获得一个变量? – S42 2011-03-08 19:46:08

+0

@ S42:请参阅我的编辑 – 2011-03-08 20:29:29

+0

ty更新;实际上创建2或3个“使用”函数可能会很好,但是知道如何编写通用函数(使用1/2/3/...函数可能委托给它)最有帮助。 – S42 2011-03-08 21:22:28

1

您需要将可变参数转换为类型系统的Seq(Scala在内部执行的操作)。

action : Seq[T] => R 
+0

Ty;这也适用。它在using块中获取单个变量而不是单个变量的问题('usingva(new FileWriter(file),new FileWriter(file)){fw => ...}')其中fw现在是一个Seq [ T],我理想地想更接近'''usingva(new FileWriter(file),new FileWriter(file)){fw1,fw2 => ...}' – S42 2011-03-08 19:52:11

相关问题