Angenommen, ich habe diese Klasse:
type Pet (name:string) as this =
let mutable age = 5
let mutable animal = "dog"
Ich möchte die Möglichkeit haben, eine neue Pet
basierend auf einigen serialisierten Daten, die ich mit diesem Datensatz darstelle:
type PetData = {
name : string
age : int
animal : string
}
(TLDR: Ich kann nicht herausfinden, die Syntax, um einen Konstruktor zu machen, die ein nehmen wird PetData
um die Bindungen zu füllen. Meine verschiedenen Versuche folgen).
Ich mache also eine neue Pet
Konstruktor, der den Let-Bindings Werte zuweist. Ich versuche, die Syntax des Klasseninitialisierers zu verwenden:
new (data:PetData) =
Pet(name,
age = data.age,
animal = data.animal
)
Hmm, nein: 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.
Ich überprüfe, ob die Syntax stimmt: keine fehlenden Kommata, korrekte "Zuweisung" ( Husten ) Operator, korrekte Einrückung.
Okay, dann versuche ich es mal mit der Syntax für die Datensatzinitialisierung.
new (data:PetData) =
{
name = data.name;
age = data.age;
animal = data.name
}
Fehler: The type 'Pet' does not contain a field 'name'
Okay, ich muss also den Hauptkonstruktor aufrufen. Ich denke, es gibt wahrscheinlich zwei Stellen, an denen ich ihn platzieren kann, also versuchen wir beide:
new (data:PetData) =
{
Pet(data.name);
age = data.age;
animal = data.name
}
Nö: Invalid object, sequence or record expression
new (data:PetData) =
Pet(data.name)
{
age = data.age;
animal = data.name
}
Und nein: 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.
Ich wollte dies nicht tun müssen, aber vielleicht, da die Felder ohnehin veränderbar sind, kann ich dem Objekt nach seiner Initialisierung einfach Werte zuweisen:
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'
Lol, was?
Okay, versuchen wir es mal so:
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
Richtig, es kann also nicht von außen auf die Bindungen zugreifen.
Versuchen wir es also mit einem Mitglied:
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.
Okay... dann versuchen wir das Ganze mal anders, mit expliziten Feldern:
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
Und dann schlage ich meiner älteren Katze ins Gesicht.
Gibt es noch andere Ideen? Diese Fehlermeldungen verwirren mich. Ich kann nicht einmal die Hälfte von ihnen bei Google finden.