0

我想了解如何優雅地使用scala.util.control.Exception包。插座連接的語言異常處理

更具體的我想這一塊的Java代碼轉換爲功能性的方式:

public static boolean hostAvailabilityCheck() { 
    try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) { 
     return true; 
    } catch (IOException ex) { 
     /* ignore */ 
    } 
    return false; 
} 

我可以在Scala中使用try-catch-finally程序做相同的,但我正在尋找更多的功能性的方式。也請注意,這個Java代碼使用try-with-resources,所以它的意思是這個代碼反正關閉套接字(即使發生異常):socket.close()

回答

3

---在問題澄清EDIT ---

要使用在斯卡拉的功能式自動資源管理,最簡單的方法是使用scala-arm,那麼你可以寫

import resource._ 

def hostAvailabilityCheck():Boolean= { 
    managed(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).map(_=>true).opt.isDefined 
} 

如果你真的,真的想用scala.util.control.Exception你可以寫:

import scala.util.control.Exception._ 
def hostAvailabilityCheck():Boolean= { 
    catching[IOException].opt(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)). isDefined 
} 
return false; 

}

更妙的是,你可以使用Try類型要做到這一點,在這種情況下,原來的方法將成爲:

def hostAvailabilityCheck():Boolean = { 
    Try(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).isSuccess 
} 

這是不從你的例子中清楚你想要做什麼,但它可能有用返回Try而不是布爾值,這樣,如果端口獲取成功,則不必在重新綁定之前等待OS級別的端口回收至 它以更確定的方式。

def hostAvailabilityCheck(port: Int):Try[Socket] = { 
    Try(new Socket(SERVER_ADDRESS, port)) 
} 

那麼你的客戶端代碼會試圖獲取一個端口,直到它實際上得到一個:

def acquire(port: Int):Socket={ 
    hostAvailabilityCheck(port).recoverWith(case t:Throwable => acquire(port)).get 
} 

這是一個幼稚的做法,因爲它會觸發一個無限循環,等待端口可用和可能試圖捕獲不可恢復的錯誤,但它應該給你一個總的想法。 只有當您使用0作爲端口值時,實現纔會真正有用,在這種情況下,它會嘗試各種隨機端口,直到找到一個空閒的端口。

+0

非常感謝您的回答。使用'Try'的選項在我看來更加優雅,但問題在於Java代碼會自動關閉新的Socket(因爲它使用try-with-resources塊)。這是我的主要問題,即如何優雅地將其轉換爲功能風格並正確關閉資源。 – MyTitle

+1

你能澄清一下,在這個問題中,我將添加一個部分 – Jean

+0

似乎非常有希望,再次感謝,但我仍然有1個錯誤:託管資源的'opt'方法沒有爲我定義。如果使用scala-arm,我使用的是最後一個版本 - 1.4 – MyTitle