【问题标题】:How to use picocli to handle option with multiple types如何使用 picocli 处理多种类型的选项
【发布时间】:2021-04-01 14:21:15
【问题描述】:

我正在将现有应用程序转换为使用 picocli。现有选项之一如下所示:

-t, --threads           [1, n] for fixed thread pool, 'cpus' for number of cpus, 'cached' for cached

这允许选项是一个正整数或几个特殊字符串之一。现有代码将其视为字符串,如果不是特殊字符串之一,则将其传递给Integer.parseInt

当然,我可以用 picocli 做同样的事情,但我想知道是否有更好的方法来处理这个问题。例如,允许将多个字段用于同一选项的东西,并根据传递的内容填写适当的字段?这也可能允许我对可能的字符串选项使用枚举。

【问题讨论】:

    标签: java picocli


    【解决方案1】:

    一个想法是为此创建一个类,比如ThreadPoolSize,它封装了一个固定数值或动态值的枚举。您需要为此数据类型创建一个自定义转换器。

    然后你可以定义选项如下:

    @Option(names = { "-t", "--threads" }, converter = ThreadPoolSizeConverter.class,
      description = "[1, n] for fixed thread pool, 'cpus' for number of cpus, 'cached' for cached")
    ThreadPoolSize threadPoolSize;
    

    线程池大小和转换器的自定义数据类型可能如下所示:

    class ThreadPoolSize {
        enum Dynamic { cpus, cached }
    
        int fixed = -1;  // if -1, then use the dynamic value
        Dynamic dynamic; // if null, then use the fixed value
    }
    
    class ThreadPoolSizeConverter implements CommandLine.ITypeConverter<ThreadPoolSize> {
    
        @Override
        public ThreadPoolSize convert(String value) throws Exception {
            ThreadPoolSize result = new ThreadPoolSize();
            try {
                result.fixed = Integer.parseInt(value);
                if (result.fixed < 1) {
                    throw new CommandLine.TypeConversionException("Invalid value " +
                            value + ": must be 1 or more.");
                }
            } catch (NumberFormatException nan) {
                try {
                    result.dynamic = ThreadPoolSize.Dynamic.valueOf(
                            value.toLowerCase(Locale.ENGLISH));
                } catch (IllegalArgumentException ex) {
                    throw new CommandLine.TypeConversionException("Invalid value " +
                            value + ": must be one of " + 
                            Arrays.toString(ThreadPoolSize.Dynamic.values()));
                }
            }
            return result;
        }
    }
    
    

    【讨论】:

    • 谢谢——这比只使用字符串要好!我想知道在 picocli 中是否有空间用于通用复合类型——例如,你创建了一个类,该类对每种可能的类型都有一个字段,并且该类得到类似 @Option(composite = true) 的内容。然后它会自动尝试按照定义的顺序将 arg 转换为每种字段类型,成功时停止。如果需要自定义转换等,也可以对内部字段进行注释。不过,这种情况可能太少了,不值得直接支持。
    • 我的直觉是,像我们在这里所做的那样,在自定义类型转换器中执行此操作比尝试将其推送到库中更干净。
    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    相关资源
    最近更新 更多