【问题标题】:Compile error while yielding a sequence through mutable variable通过可变变量产生序列时编译错误
【发布时间】:2014-07-04 12:00:04
【问题描述】:

我正在编写一个函数,它通过StringReader 接收多行字符串并将每一行作为seq 的一个项目返回

let symbolSeq = seq {

    let mutable line = reader.ReadLine()

    while !line <> null  do
        yield line
        line <- reader.ReadLine()
}

我得到了一个

这个表达式应该有类型'a ref,但这里有类型字符串

on while !--->line null do

当我去掉line前面的!时,我得到一个

可变变量“line”的使用方式无效。可变变量不能被闭包捕获。考虑通过“ref”和“!”消除这种突变的使用或使用堆分配的可变参考单元。

为什么?

【问题讨论】:

    标签: f#


    【解决方案1】:

    因为 seq 表达式会隐式创建闭包,并且您不能在 F# 中关闭可变变量。

    【讨论】:

    • @Reviewers!该死的,在拒绝之前阅读对编辑的评论。 fahadash 试图在 thr 的答案中添加一部分,thr 自己在 IRC 中写信给 fahadash。
    • @BjarkeFreund-Hansen 我删除了它,因为它与为什么它给他一个关于关闭可变值的错误的问题无关。它与字符串阅读器等无关。,
    【解决方案2】:

    您需要将 line 值放在 ref 单元格中,因为无法关闭可变值。

    let symbolSeq = seq {
    let line = ref (reader.ReadLine())
    while !line <> null do
        yield !line
        line := reader.ReadLine()
    }  
    

    【讨论】:

      【解决方案3】:

      使用 ref 单元格的替代方法是使用递归和 yield!:

      let symbolSeq =
          let rec iterate (reader : System.IO.StringReader) =
              seq
                  {
                      match reader.ReadLine() with
                          | null -> ()
                          | x ->
                              yield x
                              yield! iterate reader
                  }
      
          iterate reader
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-25
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 2020-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多