gpt4 book ai didi

F# 备用构造函数为(可变的)let 绑定(bind)赋值

转载 作者:行者123 更新时间:2023-12-04 11:58:19 30 4
gpt4 key购买 nike

假设我有这个类:

type Pet (name:string) as this =
let mutable age = 5
let mutable animal = "dog"

我希望能够创建一个新的 Pet基于一些序列化的数据,我用这条记录表示:
type PetData = {
name : string
age : int
animal : string
}

(TLDR:我无法弄清楚创建一个构造函数的语法,该构造函数将使用 PetData 来填充 let 绑定(bind)。​​接下来是我的各种尝试。)

所以我做了一个新的 Pet将值分配给 let 绑定(bind)的构造函数。我尝试使用类初始化语法:
new (data:PetData) =
Pet(name,
age = data.age,
animal = data.animal
)

嗯,不: No accessible member or object constructor named 'Pet' takes 1 arguments. The named argument 'age' doesn't correspond to any argument or settable return property for any overload.
我检查以确保我掌握了所有语法:没有缺少逗号,正确的“赋值”(咳嗽)运算符,正确的缩进。

好的,我将尝试记录初始值设定项语法。
new (data:PetData) =
{
name = data.name;
age = data.age;
animal = data.name
}

错误: The type 'Pet' does not contain a field 'name'
好的,所以我需要调用主构造函数。我想可能有两个地方可以放,所以让我们两个都试试:
new (data:PetData) =
{
Pet(data.name);
age = data.age;
animal = data.name
}

没有: Invalid object, sequence or record expression
new (data:PetData) =
Pet(data.name)
{
age = data.age;
animal = data.name
}

不: This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.
我不想这样做,但也许因为字段无论如何都是可变的,我可以在初始化对象后为其赋值:
new (data:PetData) =
let p = Pet(data.name)
p.age <- data.age
p.animal <- data.animal
p
Type constraint mismatch. The type Pet is not compatible with type PetData The type 'Pet' is not compatible with the type 'PetData'
笑什么??

好的,让我们试试这个:
let assign(data:PetData) =
this.age <- data.age
this.animal <- data.animal

new (data:PetData) =
let p = Pet(data.name)
p.assign(data)
p
The field, constructor or member 'assign' is not defined
对,所以它不能从外部访问 let 绑定(bind)。

让我们尝试一个成员:
new (data:PetData) =
let p = Pet(data.name)
p.Assign(data)
p

member x.Assign(data:PetData) =
this.age <- data.age
this.animal <- data.animal
This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.
好的......让我们尝试这整个事情不同,然后使用显式字段:
type Pet =
[<DefaultValue>]val mutable private age : int
[<DefaultValue>]val mutable private animal : string
val private name : string

new(name:string) =
{ name = name }

new(data:PetData) =
{
name = data.name;
age = data.age;
animal = data.animal
}
Extraneous fields have been given values
那是我打我老猫的脸的时候。

还有其他想法吗?这些错误消息让我失望。我什至无法在 Google 上找到其中的一半。

最佳答案

你可以这样做。

type Pet =
val mutable private age : int
val mutable private animal : string
val private name : string

new (name:string) =
{
name = name;
age = 5; // or age = Unchecked.defaultof<_>;
animal = "dog"; // or animal = Unchecked.defaultof<_>;
}

new (data:PetData) =
{
name = data.name;
age = data.age;
animal = data.animal;
}

F# 有自己的风格,看起来像这样。
type Pet(name:string, age:int, animal:string) =
let mutable age = age
let mutable animal = animal

new (name:string) =
Pet(name, 5, "dog")

new (data:PetData) =
Pet(data.name, data.age, data.animal)

编辑

添加了 do 中使用的事件每个评论请求。
type Pet(name:string, age:int, animal:string, start:IEvent<string>) =
let mutable age = age
let mutable animal = animal

// all three constructors will call this code.
do start.Add (fun _ -> printf "Pet was started")

new (name:string, start:IEvent<_>) =
// an example of different logic per constructor
// this is called before the `do` code.
let e = start |> Event.map (fun x -> x + " from 'name constructor'")
Pet(name, 5, "dog", e)

new (data:PetData, start:IEvent<_>) =
Pet(data.name, data.age, data.animal, start)

关于F# 备用构造函数为(可变的)let 绑定(bind)赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8542109/

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