gpt4 book ai didi

F#:没有默认构造函数作为类型参数的类?

转载 作者:行者123 更新时间:2023-12-01 22:43:43 25 4
gpt4 key购买 nike

我有一个 FileReader 类,它的工作是使用 StreamReader 读取和处理文本文件。为了便于单元测试,我想为此类提供一个类型参数,以便我可以将 StreamReader 替换为实际上不与文件交互的 FakeReader系统(并且可能会抛出异常,例如 OutOfMemory,因此我可以在 FileReader 中测试错误处理)。

理想情况下,我想像这样定义 FileReader(为清楚起见,已简化):

type FileReader<'Reader> =
member this.Read file =
use sr = new 'Reader(file)
while not sr.EndOfStream do
printfn "%s" <| sr.ReadLine()

并简单地定义 FakeReader 以具有一个采用文件名的构造函数、EndOfStream 属性 getter 、ReadLine() 方法,以及(空)Dispose() 方法。但是,F# 对这种类型定义有一些提示,包括 “对类型参数的对象构造函数的调用不能被赋予参数。” 由于 StreamReader 没有默认构造函数,这种方法似乎就像不行。

到目前为止,我得到它的唯一方法是从 StreamReader 继承 FakeReader:

type FakeReader() =
inherit StreamReader("") with
override this.ReadLine() = "go away"
member this.EndOfStream = false
member this.Dispose() = ()

并使用工厂方法根据需要返回新的 FakeReader 或新的 StreamReader

type ReaderType = Fake | SR
let readerFactory (file : string, readerType) =
match readerType with
| Fake -> new FakeReader() :> StreamReader
| SR -> new StreamReader(file)

type FileReader(readertype) =
member this.Read file =
use sr = readerFactory(file, readertype)
while not sr.EndOfStream do
printfn "%s" <| sr.ReadLine()

这看起来不太优雅。有没有办法用类型参数来做到这一点?感谢大家。

最佳答案

使用创建阅读器对象的函数(如 MizardX 所建议的那样)是您问题的直接答案。但是,我可能会考虑使用与 TextReader 不同的抽象。 ).正如 Ankur 在评论中提到的,您可以使用更实用的方法。

如果您只是使用 TextReader 从输入中读取文本行, 你可以使用 seq<string>改为键入。 FileReader type 实际上可能只是一个取 seq<string> 的函数(尽管这可能过于简单化了……视情况而定)。

这使它更“函数式”——在函数式编程中,您经常使用函数转换数据结构,这正是这个示例所做的:

open System.IO

/// Creates a reader that reads data from a file
let readFile (file:string) = seq {
use rdr = new StreamReader(file)
let line = ref ""
while (line := rdr.ReadLine(); !line <> null) do
yield !line }

/// Your function that processes the input (provided as a sequence)
let processInput input =
for s in input do
printfn "%s" s

readFile "input.txt" |> processInput

测试processInput函数,然后您可以创建一个新的 seq<string>值(value)。这比实现新的 TextReader 要容易得多类:

let testInput = seq {
yield "First line"
yield "Second line"
raise <| new System.OutOfMemoryException() }

testInput |> processInput

关于F#:没有默认构造函数作为类型参数的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6742747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com