我试图在F#中创建一个额外的构造函数,它执行一些额外的工作(即读取基本的csv文件),如下所示:
type Sheet () =
let rows = new ResizeArray<ResizeArray<String>>()
let mutable width = 0
new(fileName) as this =
Sheet()
then
let lines = System.IO.File.ReadLines fileName
for line in lines do
let cells = line.Split ','
rows.Add(new ResizeArray<String> (cells)) //line 16
if cells.Length > width then width <- cells.Length
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
Error 1 The namespace or module 'rows' is not defined C:\Users\ga1009\Documents\PhD\cpp\pmi\fsharp\pmi\Csv.fs 16
Error 2 The value or constructor 'width' is not defined C:\Users\ga1009\Documents\PhD\cpp\pmi\fsharp\pmi\Csv.fs 17
Error 3 The value or constructor 'width' is not defined C:\Users\ga1009\Documents\PhD\cpp\pmi\fsharp\pmi\Csv.fs 17
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
Tom*_*cek 25
正如Daniel指出的那样,F#设计是你有一个主构造函数,它通常接受类所需的所有参数并执行初始化.其他构造函数可以为参数提供默认值,也可以从其他一些信息中计算它们.
在你的情况下,我认为最好的设计是rows作为构造函数参数传递.然后,您可以添加两个额外的构造函数(一个用于加载文件,另一个用于提供空列表).
这使代码更简单,因为您不必检查是否提供了参数(如Daniel的版本).我还做了一些其他的简化(即在width功能上计算并使用序列理解 - 如果Sheet不修改数据,你也可以避免使用ResizeArray):
type Sheet private (rows) =
// The main constructor is 'private' and so users do not see it,
// it takes columns and calculates the maximal column length
let width = rows |> Seq.map Seq.length |> Seq.fold max 0
// The default constructor calls the main one with empty ResizeArray
new() = Sheet(ResizeArray<_>())
// An alternative constructor loads data from the file
new(fileName:string) =
let lines = System.IO.File.ReadLines fileName
Sheet(ResizeArray<_> [ for line in lines -> ResizeArray<_> (line.Split ',') ])
Run Code Online (Sandbox Code Playgroud)
rows并且width不在范围内.您可以让成员获取/设置它们,或者(我的建议)使构造函数具有最主要的args:
type Sheet (fileName) =
let rows = new ResizeArray<ResizeArray<string>>()
let mutable width = 0
do
match fileName with
| null | "" -> ()
| _ ->
let lines = System.IO.File.ReadLines fileName
for line in lines do
let cells = line.Split ','
rows.Add(new ResizeArray<string> (cells)) //line 16
if cells.Length > width then width <- cells.Length
new() = Sheet("")
Run Code Online (Sandbox Code Playgroud)
通常,辅助构造函数旨在成为主构造函数的重载,因此它们无法与类内部(字段)进行交互.这鼓励了单一的初始化路径(以及更好的设计).