【问题标题】:List with mixed parameterized types具有混合参数化类型的列表
【发布时间】:2016-09-04 00:06:42
【问题描述】:

给定一个带有类型参数的类型,是否可以创建一个包含混合具体类型的值的列表?请参阅下面的代码。在我尝试创建 list2 之前,一切都很好,其中一些元素有一个 int 数据,而其他元素有一个浮点数。有没有办法做到这一点?我在 list3 中的尝试无法编译。

type Holder<'data> = {
    Data : 'data
    Name : String
}

let intVal =
    {Data = 23;
    Name = "Bill"}

let intVal2 =
    {Data = 29;
    Name = "Cindy"}

let floatVal =
    {Data = 23.0;
    Name = "John"}

let list1 = [intVal; intVal2]
let list2 = [intVal; floatVal]
let list3 : Holder<'a> list = [intVal; floatVal]

【问题讨论】:

  • 否 -- F# 中的打字系统比 C# 强。你必须使用 [float intVal;浮动值]。

标签: f#


【解决方案1】:

创建列表时,列表的元素必须是同一类型。这意味着您不能创建包含Holder&lt;int&gt;Holder&lt;float&gt; 的列表。

如果你想创建一个混合类型的列表,你可以定义一个可区分的联合:

type Value = 
  | Float of Holder<float>
  | Int of Holder<int>

并使用以下命令创建Value 类型的列表:

let list = [Int intVal; Float floatVal]

或者您可以定义一个接口来捕获两者之间的共性(这里是共享的Name 属性)并创建接口类型的值列表。在您的示例中,如下所示:

type IHolder = 
  abstract Name : string

type Holder<'data> = 
  { Data : 'data
    Name : string }
  interface IHolder with
    member x.Name = x.Name

创建转换为IHolder 实例的Holder&lt;_&gt; 值列表:

let list = [intVal :> IHolder; floatVal :> IHolder]
for h in list do printfn "%s" h.Name

界面选项可让您轻松打印所有名称,但难以访问数据。使用可区分联合,类型更复杂,但您可以对其进行模式匹配以获取值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2021-12-15
    相关资源
    最近更新 更多