我正在尝试创建一个复杂类型,并且需要在构建时执行某些操作。 所以我开始编写代码:
type public MyType =
val private myvar: int
val private myvar2: string
(* ...Some val declarations... *)
new () = {
(* The default ctor makes something *)
}
new (ctorpar: AnotherType) = {
myvar = 1;
myvar2 = "Hello";
(* Other assignments in the form var = val *)
(* Here I would like to start a cycle in order *)
for i in ctorpar.array do
(* Do something *) (* ERROR *)
}
当尝试从赋值中放置for或其他内容时,编译器会发疯。 我假设如下:new的语法遵循计算表达式之一,或者更好,新的是计算表达式(我暗示这是因为大括号和从一个oinstruction到另一个oinstruction的分号)。在这种情况下,对于构造函数计算表达式,只能进行分配。
所以,请你能回答我:
1)我的演绎是否正确? (关于计算表达式和类型的构造函数)。
2)无论我是否需要在构造函数中放置一组明确的指令,我该怎么办?嗯,你知道,有时需要在施工时执行一个动作,它可能涉及从周期到所有可能性的所有事情。
但无论如何编译器都生气了......
感谢kvd我明白我有可能做到以下几点:
type public MyType =
val private myvar: int
val private myvar2: string
(* ...Some val declarations... *)
new () = {
(* The default ctor makes something *)
}
new (ctorpar: AnotherType) =
for i in ctorpar.ACollection do
(* Something *)
{
myvar = 1;
myvar2 = "Hello";
}
我很抱歉,但这对我没有帮助,因为F#编译器告诉我这个:
对象构造函数不能直接 使用try / with和try / finally之前 对象的初始化。这个 包括'for x等构造函数 in ...'可能会详细说明的用途 这些结构。这是一个限制 由Common IL强加的。
好的,如果问题是在对象初始化之前做了某些事情,并且听起来是正确的,那么让我们在以下情况之后执行此操作:
type public MyType =
val mutable private myvar: int
val mutable private myvar2: string
(* ...Some val declarations... *)
new () = {
(* The default ctor makes something *)
}
new (ctorpar: AnotherType) =
{
myvar = 1;
myvar2 = "Hello";
}
then
for i in ctorpar.ACollection do
(* Something *)
myvar <- 10
再次因失败而感到沮丧:
值'或构造函数'myvar'是 没有定义。
我该怎么办? 似乎之后,它不识别我班级中的元素,它似乎是正确的,因为它需要一个标识符,就像在使用self或this声明成员时...在这里它没有自我引用,并且正确地告诉我:“你想要得到的东西我不能给你!!!!!!”
答案 0 :(得分:13)
不,您的推断不正确。花括号更像是一个记录构造表达式,它只能包含字段赋值。 除了为大括号内的每个字段指定值外,您无法执行任何操作。
您可以在正常分配之前(即在开始大括号之前)放置语句。如果您希望之后执行其他语句,则需要使用then
关键字:
type public MyType =
val private myvar: int
val private myvar2: string
new () =
for i in 1 .. 10 do
printfn "Before field assignments %i" i
{ myvar = 1; myvar2 = "test" }
then
for i in 1 .. 10 do
printfn "After field assignments %i" i
修改强>
关于您的新问题,您可以使用new (ctorpar:AnotherType) as this = ...
,然后使用this.myvar <- 10
。
答案 1 :(得分:9)
kvb的答案很棒,并为您提供了所要求的所有信息: - )。
我只是建议使用隐式语法,其中主要构造函数紧跟在类型名称后面。这使得许多事情变得更加容易:
type MyType(n:int, s:string) =
do
// Run before fields initialized (they aren't accessible here)
for i in 1 .. 10 do
printfn "Before field assignments %i" i
// Initialize fields (accessible from now on)
let myvar = n
let myvar2 = s
do // Run after fields initialized - you can use them here
for i in 1 .. 10 do
printfn "After field assignments %i" i
// You can add multiple constructors too:
new() = MyType(0, "hi")
member x.Foo = 0