12 7 1 建立日誌記錄的計算

2021-06-01 22:50:53 字數 1353 閱讀 4781

12.7.1 建立日誌記錄的計算

這個計算將產生乙個值,並能夠將訊息寫入到本地日誌記錄的緩衝區。這意味著,計算的結果將是乙個值,和包含這些訊息的字串列表。再次,我們還是使用有乙個識別器的差別聯合,表示這個型別:

type logging<'t> =

這個生成器的實現展示在清單 12.23 中。最有趣的是,bind 成員,需要將原始值,和由計算(這是乙個函式,作為引數值給 bind 成員)的其餘部分生成的值,連線成日誌訊息。

listing 12.23 computation builder that adds logging support (f#)

type loggingbuilder() =

member x.bind(log(value, logs1), f) =

let (log(newvalue, logs2)) = f(value)

log(newvalue, logs1 @ logs2)

member x.return(value) =

log(value, )

member x.zero() =

log((), )

let log = new loggingbuilder()

1、我們要提取值。因為我們用只有一種情況的差別聯合,在成員的引數列表中,可以使用模式匹配;

2、我們需要呼叫計算的其餘部分,如果我們有乙個值在做。在清單 12.23 中,我們總是有值,所以,可以執行這個給定的函式。我們沒有立即返回結果;而是分解它,以得到在執行過程中產生的新的值和日誌訊息。

3、我們已經收集了兩個日誌訊息的緩衝,所以,需要打包這個新值,並把它新增到新的記錄器狀態。若要建立這個新狀態,要把原始訊息列表,和在呼叫計算的其餘部分時生成的新列表連線起來。這要使用列表連線運算子 (@) 來寫。

return 和 zero 成員很簡單。return 需要把實際值打包到 logging<'t> 型別中,zero 表示不攜帶任何值的計算(意思是它將返回乙個 unit)。在這兩種情況下,我們將建立乙個新的計算值,因此,這些基元返回乙個空的日誌記錄緩衝。所有的日誌訊息將以其它方式產生,並追加到 bind 成員。如果你看看到目前為止的**,沒有任何方法,可以建立乙個非空的日誌 !這意味著,我們會需要建立乙個額外的基元,以建立包含日誌訊息的計算值。我們可以把它寫成乙個簡單的函式:

> let logmessage(s) =

log((), [s])

val logmessage : string -> logging

這個函式建立乙個計算值,它包含乙個 unit 值。更重要的是,在日誌記錄的緩衝中,它還包含一條訊息,因此,如果我們使用 bind 把它與另乙個計算組合起來,得到乙個計算,以寫到日誌中。現在,我們終於可以寫**,使用新建立的日誌記錄計算。

12 7 1 建立日誌記錄的計算

12.7.1 建立日誌記錄的計算 這個計算將產生乙個值,並能夠將訊息寫入到本地日誌記錄的緩衝區。這意味著,計算的結果將是乙個值,和包含這些訊息的字串列表。再次,我們還是使用有乙個識別器的差別聯合,表示這個型別 type logging t 這個生成器的實現展示在清單 12.23 中。最有趣的是,bi...

CStdioFile類建立日誌記錄檔案

1,cstdiofile類建立日誌檔案,定義全域性變數,每個需要記錄位置的地方,以當前時間作為檔名稱 log text 全域性變數 cstdiofile g logfile 日誌檔案 cstring filename ctime tm ctime getcurrenttime filename tm...

12 7 給計算增加日誌記錄

12.7 給計算增加日誌記錄 日誌通常可以使用全域性可變狀態實現。然而,如果我們想要避免使用全域性可變狀態,並保持程式的純函式性,又會如何呢?我們會有乙個選擇,就是把日誌記錄器的狀態作為額外的引數值,傳遞我們要呼叫的每個函式。實現可能非常困難 想象一下,如果我們決定將另乙個引數新增到這個狀態中!要解...