我正在重构F#中的程序,试图在不使用关键字mutable的情况下100%完成该程序,但是此功能存在问题:
let ReadAndProcessCardData() =
let mutable pasobyte = serialPort1.BytesToRead
let mutable pasobyte2 = 0
while (pasobyte <> pasobyte2)
do
pasobyte <- serialPort1.BytesToRead
Thread.Sleep(2);
pasobyte2 <- serialPort1.BytesToRead
let mutable arr = [| for i in 1..serialPort1.BytesToRead -> byte(i*i)|]
serialPort1.Read( arr , 0 , arr.Length ) |>ignore
ByteArrayToString(arr) |> printCardGuid
我正在尝试等待几毫秒,然后检查到达串行端口的流是否已结束,或者仍然有更多数据进入,但是如果我编译了函数,则BytesToRead属性会在我读取它之前更改作为递归而不是while循环,它获取的值是一个常量,我知道这是一个不纯函数,我想知道什么是重构函数的正确方法,以及如何对其进行更改以使其成为100的纯函数尽可能删除“可变”一词,但保持其行为。 谢谢
答案 0 :(得分:1)
您可以将while
循环转换为递归函数,而无需做很多工作。此外,最好将串行端口作为参数传递。然后,该函数将大致如下所示:
let readAndProcessCardData (sp : System.IO.Ports.SerialPort) =
let rec waitLoop b1 b2 =
if b1 = b2 then b1 else
let bb1 = sp.BytesToRead
Thread.Sleep 2
let bb2 = sp.BytesToRead
waitLoop bb1 bb2
let readLen = waitLoop 0 1
let arr = Array.zeroCreate readLen
sp.Read (arr, 0, arr.Length) |> ignore
byteArrayToString arr |> printCardGuid