myślę, że to dobrze znane ograniczenie F #, ale nie mogłem znaleźć żadnych dobrych obejścia ...F # cytaty, tablice i własny identyfikator w konstruktorów
Więc tutaj jest kod (starałem się zrobić to jak proste, jak to możliwe, więc prawdopodobnie to wygląda to nie ma żadnego sensu):
[<ReflectedDefinition>]
type Human (makeAName: unit -> string) as self =
let mutable cats : Cat array = [| |]
do
// get a cat
cats <- Array.append cats [| new Cat (self, makeAName()) |]
member this.Cats = cats
and
[<ReflectedDefinition>]
Cat (owner : Human, name : string) = class end
kompilator mówi:
błąd FS0452: notowania nie może zawierać wbudowany kod montaż lub wzorzec dopasowania na tablicach
W rzeczywistości jest to połączenie as self
i gettera właściwości tablicy, który przerywa wszystko.
Tutejsze punkty to:
- naprawdę chcę użyć tablice, bo chcę WebSharper tłumaczyć swoje kolekcje do tablic obsługi JavaScript.
- Naprawdę potrzebuję identyfikatora w konstruktorach.
- Naprawdę potrzebuję klas (tj. Styl funkcjonalny nie zadziała).
- Identyfikatory dla każdej metody (
member this.Foo
) działają bez zarzutu.
Jednym z obejść, jaki mogę wymyślić, jest tworzenie konstruktorów jako prywatnych i stosowanie metod statycznych do konstruowania obiektów. W ten sposób nie potrzebuję as self
. Ale to po prostu głupie.
Czy są jakieś lepsze opcje?
Aktualizacja:
Tutaj jest jeszcze prostszy przykład:
[<ReflectedDefinition>]
type User (uid: int) as self =
let ROOT_UID = 0
member this.isRoot = (uid = ROOT_UID)
Z as self
nawet nie mogę określić stałą klasą. Cóż, to właściwie osobne pytanie, ale zadam to tutaj: jak zdefiniować stałą klasy w tym konkretnym przypadku?
Statyczne konstruktory-fine.Speaking o drugim przykładzie, dobrze, prawo, stała modułu działa, ale ja w rzeczywistości jest to stała klasy, dlatego chcę umieścić w klasie. Posiadanie stałych klas w klasach (i nieprzebywanie przestrzeni nazw modułu) wydaje się rozsądną rzeczą do zrobienia. – kirelagin