2011-03-08 34 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

相關問題