繁体   English   中英

在F#中使用泛型创建EnumArray类型

[英]Using generics in F# to create an EnumArray type

我创建了一个F#类来表示一个数组,该数组为特定枚举的每个值分配一个元素。 我正在使用一个显式构造函数,该构造函数创建一个从枚举值到数组索引的字典,以及一个Item属性,以便您可以编写如下表达式:

let my_array = new EnumArray<EnumType, int>
my_array.[EnumType.enum_value] <- 5

但是,在下面标记为“ // FS0670”的行上出现以下晦涩的编译错误。

error FS0670: This code is not sufficiently generic.
The type variable  ^e when  ^e : enum<int> and  ^e : equality
and  ^e : (static member op_Explicit :  ^e -> int)
could not be generalized because it would escape its scope.

我很茫然-有人可以解释这个错误吗?

type EnumArray< 'e, 'v when 'e : enum<int>  //'
                       and 'e : equality
                       and 'e : (static member op_Explicit :  'e -> int) > =
    val enum_to_int : Dictionary<'e, int>  //'
    val a : 'v array  //'

    new() as this =
        { 
            enum_to_int = new Dictionary<'e, int>()  //'
            a = Array.zeroCreate (Enum.GetValues(typeof<'e>).Length)  //'
        }
        then
            for (e : obj) in Enum.GetValues(typeof<'e>) do  //'
                this.enum_to_int.Add(e :?> 'e, int(e :?> 'e))

    member this.Item
        with get (idx : 'e) : 'v = this.a.[this.enum_to_int.[idx]]  // FS0670
        and set (idx : 'e) (c : 'v) = this.a.[this.enum_to_int.[idx]] <- c

干得好:

open System
open System.Collections.Generic 

type EnumArray<'e, 'v when 'e : enum<int> and 'e : equality>() = 
    let dict = new Dictionary<'e, int>()    //'
    let values = Enum.GetValues(typeof<'e>) //'
    let a = Array.zeroCreate values.Length
    do
        for (o : obj) in values do 
            let e = o :?> 'e   //'
            dict.Add(e, LanguagePrimitives.EnumToValue(e)) 
    member this.Item 
        with get idx  = a.[dict.[idx]]
        and set idx c = a.[dict.[idx]] <- c

let d = new EnumArray<StringSplitOptions, string>()
d.[StringSplitOptions.None] <- "foo"
d.[StringSplitOptions.RemoveEmptyEntries] <- "bar"

一个关键方面是LanguagePrimitives.EnumToValue ,它消除了对静态成员约束的需要。 (使用静态成员约束已经足够糟糕,但是当它们失败时,编译器诊断会更糟。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM