API Basic Using zh tw - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki

Using / End Using

ClassicUO • Basic

Using 會在離開區塊時關閉原生資源。目前支援既有變數,或傳回資源的運算式。

完整語法

Dim resource = MemoryStream()
Using resource
    statements
End Using
Using resourceExpression
    statements
End Using

參數

  • resourceExpression — 進入時只計算一次。可使用 File(path)、MemoryStream() 與 CreateTimer(...)。釋放計時器會永久停止它,請參閱 Basic.Timers。String、數字、List、Dictionary 會在執行區塊前引發含來源行號的錯誤。請先宣告變數;不支援標頭內宣告、As New、逗號資源清單及使用者 Dispose 方法。
  • statements / End Using — End Using 關閉已擷取的物件。變數仍可存取,但資源已關閉。多個資源請使用巢狀區塊。重新指派變數不會改變最後要關閉的原始物件。

傳回值

此陳述式沒有傳回值。區塊內的 Return 會先釋放資源再離開程序。範例 IsClosed 是自訂函式,回傳 1/True 或 0/False;Main 的最終結果是字串,不是成功旗標。

行為

  • File(path) 建立包裝物件;在區塊內呼叫 Create() 寫入,或 Open() 讀取。Dispose 呼叫 Close()、清空緩衝區並釋放控制代碼。MemoryStream 關閉後,Length() 會出錯。範例只使用記憶體,不建立檔案。
  • 編譯器建立受保護區域;直譯器在目前呼叫中保存物件。End Using、Return、Exit、Continue 或跳出會由內而外關閉資源。跳入區塊會在執行前遭拒絕。
  • 一般錯誤會在外層 Catch 前關閉資源。失敗的 Dispose 不會重試,外層資源仍會釋放。緊急停止略過腳本 Catch/Finally,仍關閉原生資源;關閉錯誤不取代取消。暫停會保留資源直到繼續或停止。這不建立執行緒,也不能強制中斷作業系統阻塞中的關閉操作。
  • 若需處理錯誤並保持資源開啟,請將 Try/Catch 放在 Using 內。On Error Resume Next 遇到未處理的本體錯誤時會關閉資源,從整個區塊之後繼續。On Error GoTo 不得指向 Using 內的標籤,以免重新進入已關閉的保護區域。
  • 錯誤離開 Using 後,外部 On Error GoTo 處理常式的 Resume 會從標頭重新執行整個區塊,再次計算資源運算式;Resume Next 則接續 End Using 後的第一行。若變數仍指向已關閉的物件,重新進入不會重新開啟它;重試時應使用會取得新資源的運算式。先前執行過的操作可能重複。

範例

1. 關閉記憶體串流

# stream 是資源;size 在開啟時讀得 Length()=0。End Using 後,IsClosed 擷取錯誤並回傳 True=1,Main 回傳 "0:1"。ByVal 複製參考而非串流。此教學函式將任何 Length 錯誤視為關閉,只適用於這些串流。
Option Explicit On
Function IsClosed(ByVal stream) As Boolean
    Try
        Dim size = stream.Length()
        Return False
    Catch closed
        Return True
    End Try
End Function

Sub Main()
    Dim stream = MemoryStream()
    Dim size = -1
    Using stream
        size = stream.Length()
    End Using
    Return CStr(size) & ":" & CStr(IsClosed(stream))
End Sub

參數與執行說明:

stream 是資源;size 在開啟時讀得 Length()=0。End Using 後,IsClosed 擷取錯誤並回傳 True=1,Main 回傳 "0:1"。ByVal 複製參考而非串流。此教學函式將任何 Length 錯誤視為關閉,只適用於這些串流。

2. 從輔助函式返回

# ReadLength(stream) 算出 Integer 0。Return 在 Main 收到 size 前關閉串流。之後 Length 出錯,使 closed=True,結果為 "0:1"。若呼叫端仍需要開啟的資源,就不要傳入此函式。
Option Explicit On
Function ReadLength(ByVal stream) As Integer
    Using stream
        Return stream.Length()
    End Using
End Function

Sub Main()
    Dim stream = MemoryStream()
    Dim size = ReadLength(stream)
    Dim closed = False
    Try
        Dim after = stream.Length()
    Catch problem
        closed = True
    End Try
    Return CStr(size) & ":" & CStr(closed)
End Sub

參數與執行說明:

ReadLength(stream) 算出 Integer 0。Return 在 Main 收到 size 前關閉串流。之後 Length 出錯,使 closed=True,結果為 "0:1"。若呼叫端仍需要開啟的資源,就不要傳入此函式。

3. 錯誤時巢狀釋放

# outer 與 inner 是不同串流。Throw "demo" 先關閉 inner,再關閉 outer。Catch 保存原始訊息;兩次 IsClosed 各回傳 1,Main 結果為 "demo:2"。2 是關閉物件數量,並非 Boolean。
Option Explicit On
Function IsClosed(ByVal stream) As Boolean
    Try
        Dim size = stream.Length()
        Return False
    Catch closed
        Return True
    End Try
End Function

Sub Main()
    Dim outer = MemoryStream()
    Dim inner = MemoryStream()
    Dim message = ""
    Try
        Using outer
            Using inner
                Throw "demo"
            End Using
        End Using
    Catch problem
        message = problem
    End Try
    Return message & ":" & CStr(IsClosed(outer) + IsClosed(inner))
End Sub

參數與執行說明:

outer 與 inner 是不同串流。Throw "demo" 先關閉 inner,再關閉 outer。Catch 保存原始訊息;兩次 IsClosed 各回傳 1,Main 結果為 "demo:2"。2 是關閉物件數量,並非 Boolean。


en · ru · uk · fr · de · it · es · zh-tw · ja · ko

Basic