簡體   English   中英

如何將 TextWriterFormat 的強大功能用於 printfn 樣式,並結合需要單位結果的 ConditionalAttribute

[英]How to leverage power of TextWriterFormat for printfn style in combination with ConditionalAttribute which requires unit result

我設置自己創建一個跟蹤函數,其行為類似於sprintfprintfn ,但通過使用ConditionalAttribute為發布版本禁用(JIT 在調用站點上將其刪除)。

到目前為止的結果:我認為這是不可能的。

問題圍繞這樣一個事實:當您使用Conditional("DEBUG")屬性時,該函數必須返回單位結果。 “正常”參數按其應有的方式工作,並且方法已正確裝飾(編輯:裝飾,是的,但不會刪除可咖喱成員,請參閱討論,必須改用元組形式):

type Trace() =    
    [<Conditional("DEBUG")>]
    static member inline trace msg b = (msg, b) |> ignore

// using it, x is unit
let x = Trace.trace "test" "foo"

(請注意,如果沒有ignore ,由於 Conditional 屬性,這將無法編譯)

但是,一旦我嘗試Printf.TextWriterFormat<'T>任何變體,它就會失敗並且我看不到解決方法:

type Trace() =
    [<Conditional("DEBUG")>]
    static member inline trace msg = printfn msg    // inline or not doesn't matter

    // using it, x is unit
    let x = Trace.trace "hello: %s" "foobar"

這在沒有屬性的情況下工作,但有了屬性,它會引發:

此表達式應具有類型
unit
但這里有類型
string -> unit

該錯誤特別強調了Trace.trace "hello: %s" 所以看起來編譯器沒有識別出整個表達式結果是一個unit ,並引發錯誤,因為它在內部創建了一個返回string -> unit的包裝函數,這是ConditionalAttribute的規則所不允許的。

當我嘗試通過在函數返回類型上顯式指定:unitprintfn msg |> ignore作為主體來修復它時,我將失去使用具有類型安全性的文本printfn msg |> ignore格式字符串的能力,事實上,它不會不再識別呼叫站點上的第二個參數。

因此,雖然整個函數簽名都遵守 CLR 的規則,但 F# 創建的內聯函數似乎沒有,至少在這種特定情況下沒有。

我嘗試了變體,包括kprintfsprintf ,看看是否有幫助,但都無濟於事。

有任何想法嗎? 或者這是您嘗試鋪設地毯的情況之一,一旦您在一個角落適當地平滑它,它就會在另一個角落冒泡,反之亦然,即它永遠不會適合?


PS:如果您想知道我為什么想要它:只是嘗試創建一個行為類似於現有 Trace 的便利函數,但在幕后還有其他一些功能。 我目前擁有的作品,但它只需要一個字符串,而不是一個靜態類型檢查參數,所以它迫使用戶編寫如下內容:

(sprintf "Hello %s" >> Trace.trace) "foobar"

基於重載的版本。

你可能想要更多的重載

#if DEBUG
type Log() =
    static member inline log(x) = printfn x
    static member inline log(x,y) = printfn x y
#else
type Log =
    static member inline log(x) = ()
    static member inline log(x,y) = ()
#end

更新:

所以這有效:

open System.Diagnostics
type Log() =
    [<Conditional("DEBUG")>]  
    static member log(x) = printfn x
    [<Conditional("DEBUG")>]
    static member log(x,y) = printfn x y

您需要切換到元組形式以允許重載並使用元組形式,因為柯里化的東西不能重載

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM