在 sml 中从命令行传递两个参数

Pass two arguments from command line in sml

我想从命令行传递两个参数。我知道如何使用 CommandLine.arguments 传递一个参数。

val arg1 = CommandLine.arguments();

但是如何传递两个参数并使用呢?

谢谢。

CommandLine.arguments的类型是

unit -> string list

它 return 不是一个字符串,它 return 是一个字符串列表。任何传递的参数都将在列表中。你只需要提取它们。

如果你传递的是一个字符串,它分成多个参数,而不是 space 作为分隔符,你可以在它上面使用 String.tokens。例如,

String.tokens (fn c => c = #"|") "abc|de|fgh";

产生 ["abc","de","fgh"]。您需要向 String.tokens 传递一个布尔值函数,该函数可以判断字符何时为定界符。

正如 John 所说,由于 CommandLine.arguments : unit -> string list,您可以通过此列表上的常规模式匹配来提取第一个和第二个参数。假设前两个参数可以命名为 foobar,并且都应该被解释为字符串,并且任何其他数量的参数 (0, 1, 3, ...) 是一个错误,你可以这样写:

fun main () =
    let val (foo, bar) = case CommandLine.arguments () of
                              [foo, bar] => (foo, bar)
                            | _ => raise Fail "Usage: tool <foo> <bar>"

    in ...
    end

并且对 foobar 执行转换,例如转换为数字,从这里开始并不十分困难。但是如果你的命令行参数是可选的,或者你不希望它们的顺序很重要,或者你想提供多种方式来指定它们——例如-h--human-readable 的别名,而两者都有效 – 您应该考虑在 SML/NJ 中使用名为 GetOpt 的实用程序库。

它提供了一个框架,用于指定应如何以动态方式解释命令行参数。你可以阅读SML/NJ GetOpt documentation,它提供了一个小例子。这是一个非常通用的库,并增加了一些复杂性,除非您有很多参数并且懒得处理它们的所有合法组合,否则这种复杂性可能是不必要的。

我想通了: 只需使用

sml "file.sml" "arg1" "arg2"

其中 arg1 和 arg2 存储在列表中,可以使用列表的 "tl" 和 "hd" 函数在程序中提取。