我有这种方法,它接受一个列表并将其转换为字节码字符串。它以我期望的方式工作;但是,我得到了一个我不想要的尾随空间。 问题:如何摆脱最后的尾随0?

Input: byteCode [SC 10; SC 2; SAdd; SC 32; SC 4; SC 5; SAdd; SMul; SAdd]

let rec byteCode (l : sInstr list) : string =
  match l with
  | [] -> ""
  | (SC    n :: l)     -> "0 " + string n + " " + byteCode l
  | (SAdd    :: l)     -> "1 " + byteCode l
  | (SSub    :: l)     -> "2 " + byteCode l
  | (SMul    :: l)     -> "3 " + byteCode l
  | (SNeg    :: l)     -> "4 " + byteCode l
  | (SLess   :: l)     -> "5 " + byteCode l
  | (SIfze n :: l)     -> "6 " + string n + " " + byteCode l
  | (SJump n :: l)     -> "7 " + string n + " " + byteCode l

这可能不会编译,因为我没有给出整个程序。
This returns: "0 10 0 2 1 0 32 0 4 0 5 1 3 1 "
I expect:     "0 10 0 2 1 0 32 0 4 0 5 1 3 1"

最佳答案

诸如此类的情况通常表明字符串以太幼稚的方式连接在一起。考虑首先收集结果的所有各个组成部分,然后调用预定义的String.concat函数:

let byteCode (l : sInstr list) : string =
    let rec byteCode' l =
        match l with
        | [] -> []
        | (SC    n :: l)     -> "0" :: string n :: byteCode' l
        | (SAdd    :: l)     -> "1" :: byteCode' l
        | (SSub    :: l)     -> "2" :: byteCode' l
        | (SMul    :: l)     -> "3" :: byteCode' l
        | (SNeg    :: l)     -> "4" :: byteCode' l
        | (SLess   :: l)     -> "5" :: byteCode' l
        | (SIfze n :: l)     -> "6" :: string n :: byteCode' l
        | (SJump n :: l)     -> "7" :: string n :: byteCode' l

    l |> byteCode' |> String.concat " "
String.concat已经仅在各个部分之间添加了分隔符字符串。

这也更加简洁,因为它将特定分隔符字符串的实现细节保留在您的核心逻辑之外,并使它更易于替换-想象一下将其简单地更改为函数中两个空格的工作量。

或者,您可以只使用现有函数,然后在最终产生的字符串上调用.Trim()(或.TrimEnd())方法来删除(尾部)空格。

10-08 13:42