You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在F#中打印调用函数时传入的实参函数名称?

解决F#中打印传入函数的实参名称问题

核心思路

nameof是编译时操作符,只能获取当前作用域内的符号名称(比如形参f)。要拿到传入的实参函数名,需要借助F#的**代码引用(Quotations)**功能——它能捕获代码的结构信息,包括原函数的名称标识。

修改后的实现代码

open System
open System.Threading.Tasks
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

// 辅助函数:从代码引用中解析函数名称
let getFunctionName (expr: Expr<'a -> Task<'b>>) =
    match expr with
    | Lambda (_, Call (_, methodInfo, _)) -> methodInfo.Name
    | Lambda (_, PropertyGet (_, propInfo, _)) -> propInfo.Name
    | _ -> failwith "无法识别的函数形式"

// 改造后的logger函数,接收函数的代码引用
let logger (expr: Expr<'a -> Task<'b>>) : ('a -> Task<'b>) =
    let funcName = getFunctionName expr
    printfn "Hey: %s" funcName
    // 将引用编译为可执行函数
    expr.Evaluate()

let myFunc x = task { return x }

// 调用时用<@ ... @>包裹函数,传入代码引用
let d = (logger <@ myFunc @>) 3

代码说明

  1. 引用包裹:调用logger时,用<@ myFunc @>将目标函数包装成代码引用,保留myFunc的名称元信息。
  2. 解析名称:getFunctionName通过匹配引用的模式(如Lambda、PropertyGet),提取出原函数的名称字符串。
  3. 编译执行:expr.Evaluate()将代码引用转换成可执行的函数,保证原函数的业务逻辑不受影响。

注意事项

  • 若传入匿名函数,这种方法无法获取有效名称,可根据需求扩展错误处理逻辑。
  • 项目需确保引用Microsoft.FSharp.Linq包(.NET Core/.NET 5+项目通常已默认包含)。

内容的提问来源于stack exchange,提问作者Tuomas Hietanen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:55:25