我正在尝试制作一个包含多种可能类型的集合.这是我希望它看起来的一个例子:
type Position = Vector2
type Velocity = Vector2
type Appearance = String
type Component = Position | Velocity | Appearance
let components = List<Dictionary<string, Component>>()
let pos = Dictionary<string, Position>()
components.Add(pos) // Type "Position" does not match with type "Component"
Run Code Online (Sandbox Code Playgroud)
我想声明仍然适合一般类型的特定类型.有没有办法可以像这样写我的代码?有没有比较惯用的方法呢?
您的代码中有几件事情:
类型缩写(链接)
type Position = Vector2
type Velocity = Vector2
type Appearance = String
Run Code Online (Sandbox Code Playgroud)
类型缩写只是为现有类型定义另一个名称,左侧和右侧的类型和精确等效,可以互换使用.
举一个与这个问题相关的例子,在F#中有一个标准.NET的类型缩写List,它被称为ResizeArray.它的定义如下:
type ResizeArray<'T> = System.Collections.Generic.List<'T>
Run Code Online (Sandbox Code Playgroud)
它可以节省您打开System.Collections.Generic以便使用它,它有助于避免与listF#中的类型混淆,但除了为现有类型添加新名称之外,它不会执行任何操作.
受歧视的联盟(链接)
type Component = Position | Velocity | Appearance
Run Code Online (Sandbox Code Playgroud)
在这里,你有一个单一的类型,称为Component,你可以把它作为一个单一类型三个构造函数:Position,Velocity和Appearance.您还可以通过模式匹配使用相同的三种情况再次解构类型.
例如
match comp with
|Position -> ..
|Velocity -> ..
|Appearance -> ..
Run Code Online (Sandbox Code Playgroud)
希望,Position您声明的类型缩写与Position您声明为Component类型的一部分的union case没有任何关联,现在应该不足为奇 了.它们完全相互独立.
Position意味着Vector2并且Component是一种完全独立的联合类型.
假设您想要一个Component可以包含多个内容的类型,您需要将一些值与案例相关联.以下是创建此类歧视联盟的示例:
type Component =
| Position of Vector2
| Velocity of Vector2
| Appearance of string
Run Code Online (Sandbox Code Playgroud)
现在,让我们看看下一个问题.
如果我们删除类型缩写并使用我们新的Discriminated Union尝试其余代码
let components = List<Dictionary<string, Component>>()
let pos = Dictionary<string, Position>()
Run Code Online (Sandbox Code Playgroud)
我们现在有一个新错误:
类型
Position未定义.
好吧,记住我之前说的话Component. Component是类型,Position不是类型,它是一个联合案例Component.
如果您想要包含这些选项中相同选项的完整词典,您可能最好将定义更改为以下内容:
type ComponentDictionary =
|PositionDictionary of Dictionary<string, Vector2>
|VelocityDictionary of Dictionary<string, Vector2>
|AppearanceDictionary of Dictionary<string, string>
Run Code Online (Sandbox Code Playgroud)
然后你可以创建一个ResizeArray/ List.
let components = ResizeArray<ComponentDictionary>()
Run Code Online (Sandbox Code Playgroud)
现在,为了填充这个集合,我们只需要使用适当的case构造函数 ComponentDictionary
let pos = PositionDictionary (Dictionary<string, Vector2>())
Run Code Online (Sandbox Code Playgroud)
现在,pos是类型,ComponentDictionary所以我们可以将它添加到组件:
components.Add(pos) // No error here!
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
94 次 |
| 最近记录: |