ocaml printf函数:如果满足某些条件,则完全跳过格式化 [英] ocaml printf function: skip formatting entirely if some condition holds

查看:129
本文介绍了ocaml printf函数:如果满足某些条件,则完全跳过格式化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(摘录自 ocaml:在对象的方法中公开printf函数,因此可以独立地对其进行回答)

(extracted from ocaml: exposing a printf function in an object's method, so it can be answered independently)

对于记录器,我具有以下(简化的)ocaml代码:

I have the following (simplified) ocaml code, for a logger:

type log_level =
    | Error
    | Warn
    | Info

let ord lvl =
    match lvl with
    | Error -> 50
    | Warn  -> 40
    | Info  -> 30

let current_level = ref (ord Warn)

let logf name lvl =
    let do_log str =
        if (ord lvl) >= !current_level then
            print_endline str
    in
    Printf.ksprintf do_log

logf函数可以与printf格式一起使用,例如:

The logf function can be used with a printf format, as in:

logf "func" Warn "testing with string: %s and int: %d" "str" 42;

有什么方法可以实现仅在实际需要时仅格式化参数的典型记录行为吗?,例如:

let logf name lvl <args> =
    if (ord lvl) >= !current_level then
        Printf.printf <args>

我想是因为只有编译器才知道格式表达式中有多少个参数,而我猜ocaml中没有像varargs这样的东西吗?因此,您永远无法定义printf函数的 full 主体,只能使用currying并让编译器神奇地解决它.有什么方法可以实现我想要的吗?也许使用mkprintf?

I'm thinking it's because only the compiler knows how many arguments there will be in a format expression, and I guess there's no such thing as varargs in ocaml? So you can't ever define the full body of a printf function, you can only use currying and let the compiler magic figure it out. Is there any way to achieve what I want? Perhaps with mkprintf?

推荐答案

专门提供了诸如Printf.kfprintf之类的延续功能,以允许诸如此类的格式包装.看起来像这样:

The continuation functions such as Printf.kfprintf are provided specifically to allow format wrappers such as this. It looks something like this:

open Printf

type log_level = Error | Warn | Info

let ord = function Error -> 50 | Warn  -> 40 | Info  -> 30

let string_of_lvl = function
  | Error -> "error"
  | Warn -> "warn"
  | Info -> "info"

let current_level = ref (ord Warn)

let printf_with_info name lvl =
  kfprintf fprintf stdout "[<%s>] <%s>: " name (string_of_lvl lvl)

let logf name lvl =
  if ord lvl >= !current_level then match lvl with
   | Error | Warn -> printf
   | Info -> printf_with_info name lvl
  else
    ifprintf stdout

这篇关于ocaml printf函数:如果满足某些条件,则完全跳过格式化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆