Istnieje kilka rzeczy, które mają w swojej kod tutaj:
Rodzaj Skróty (Link)
type Position = Vector2
type Velocity = Vector2
type Appearance = String
Rodzaj skróty wystarczy zdefiniować inną nazwę dla istniejącego typu, rodzaju na w lewo i w prawo i dokładnie równoważne i mogą być używane zamiennie.
Aby podać przykład odnoszący się do tego pytania, w języku F # znajduje się skrót nazwy standardu .NET List
, nazywa się to ResizeArray
. Jest zdefiniowany następująco:
type ResizeArray<'T> = System.Collections.Generic.List<'T>
To oszczędza konieczności otwierania System.Collections.Generic
w celu wykorzystania go i pomaga uniknąć nieporozumień z typem w F # list
ale nie coś innego niż dodać nową nazwę zrobić istniejący typ.
Disciminated Związki (Link)
type Component = Position | Velocity | Appearance
Tutaj masz jeden typ o nazwie Component
, można myśleć o nim jako o jednym typie z trzech konstruktorów: Position
, Velocity
i Appearance
. Możesz również ponownie zdekonstruować ten typ, używając tych samych trzech przypadków, dopasowując wzorzec.
np.
match comp with
|Position -> ..
|Velocity -> ..
|Appearance -> ..
Mamy nadzieję, że powinna ona teraz dziwić, że skrót typ Position
że zadeklarowana nie ma związku ze sprawą unii Position
że zadeklarowane jako część typu Component
. Są całkowicie niezależni od siebie.
Position
oznacza Vector2
i Component
jest całkowicie oddzielnym typem związku.
Zakładając, że chcesz mieć typ Component
, który może zawierać wiele elementów, musisz powiązać niektóre wartości z przypadkami. Oto przykład utworzenia takiej unii dyskryminowanych:
type Component =
| Position of Vector2
| Velocity of Vector2
| Appearance of string
Teraz spójrzmy na kolejnym problemem.
Gdybyśmy usunąć skróty typu i spróbować reszty kodu z naszym nowym dyskryminowanych Unii
let components = List<Dictionary<string, Component>>()
let pos = Dictionary<string, Position>()
Mamy teraz nowy błąd:
The type Position
is not defined.
Cóż, pamiętam, co powiedziałem wcześniej około Component
. Component
jest typem, Position
nie jest typem, jest to sprawa zbiorowa z Component
.
Jeśli chciał zawierać całe słowniki tym samym jednym z tych opcji może być lepiej zmieniając definicję na coś takiego:
type ComponentDictionary =
|PositionDictionary of Dictionary<string, Vector2>
|VelocityDictionary of Dictionary<string, Vector2>
|AppearanceDictionary of Dictionary<string, string>
Następnie można utworzyć ResizeArray
/List
z nich.
let components = ResizeArray<ComponentDictionary>()
Teraz, w celu zaludnionych tej kolekcji, to wtedy wystarczy użyć odpowiedniego konstruktora skrzynka dla ComponentDictionary
let pos = PositionDictionary (Dictionary<string, Vector2>())
Teraz, poz jest typu ComponentDictionary
więc możemy dodać go do:
components.Add(pos) // No error here!
Czy rozumiesz, że Component.Position i Position nie są jednym i tym samym? –