5

コードにバグがあり、F#と遅延評価の詳細の一部がよくわからないと思います。F#は熱心に評価するため、次の関数に多少戸惑うことを知っています。

// Open a file, then read from it. Close the file. return the data.
let getStringFromFile =  
    File.OpenRead("c:\\eo\\raw.txt")
    |> fun s -> let r = new StreamReader(s)
                let data = r.ReadToEnd
                r.Close()
                s.Close()
                data

これをFSIで呼び出すと:

> let d = getStringFromFile();;

System.ObjectDisposedException: Cannot read from a closed TextReader.

at System.IO.__Error.ReaderClosed()
at System.IO.StreamReader.ReadToEnd()
at <StartupCode$FSI_0134>.$FSI_0134.main@()
Stopped due to error

これは私にそれgetStringFromFileが怠惰に評価されていると思わせます-それで私は完全に混乱しています。F#が関数を評価する方法については何もわかりません。

4

2 に答える 2

10

何が起こっているのかを簡単に説明するには、ここから始めましょう。

let getStringFromFile =  
    File.OpenRead("c:\\eo\\raw.txt")
    |> fun s -> let r = new StreamReader(s)
                let data = r.ReadToEnd
                r.Close()
                s.Close()
                data

関数の最初の2行を次のように書き直すことができます。

let s = File.OpenRead(@"c:\eo\raw.txt")

次に、このメソッドの括弧を省略しました。

            let data = r.ReadToEnd
            r.Close()
            s.Close()
            data

結果として、dataタイプはunit -> string。関数からこの値を返すと、全体の結果はになりunit -> stringます。しかし、変数を割り当ててから返すまでの間に何が起こるかを見てください。ストリームを閉じました。

最終的に、ユーザーが関数を呼び出すと、ストリームはすでに閉じられているため、上記のエラーが発生します。

use whatever = ...また、の代わりに宣言してオブジェクトを破棄することを忘れないでくださいlet whatever = ...

それを念頭に置いて、ここに修正があります:

let getStringFromFile() =  
    use s = File.OpenRead(@"c:\eo\raw.txt")
    use r = new StreamReader(s)
    r.ReadToEnd()
于 2010-09-15T17:42:55.027 に答える
2

あなたはあなたのファイルから読みません。ReadToEndのインスタンスのメソッドをStreamReader値にバインドdataし、を呼び出すときにそれを呼び出しますgetStringFromFile()。問題は、この時点でストリームが閉じていることです。

かっこを見逃していると思います。正しいバージョンは次のとおりです。

// Open a file, then read from it. Close the file. return the data.
let getStringFromFile =  
    File.OpenRead("c:\\eo\\raw.txt")
    |> fun s -> let r = new StreamReader(s)
                let data = r.ReadToEnd()
                r.Close()
                s.Close()
                data
于 2010-09-15T17:50:06.460 に答える