2010-02-02 28 views
9

Tôi đã bị một loại liệt kê được xác định như sau:Làm thế nào để liệt kê một enum/loại trong F #

type tags = 
    | ART = 0 
    | N = 1 
    | V = 2 
    | P = 3 
    | NULL = 4 

là có một cách để làm một for ... in tags do?

Đây là lỗi mà tôi nhận được:

Giá trị, xây dựng, không gian tên hoặc loại tags không được định nghĩa

+2

không phải là điều kiện, đó là công đoàn. –

+0

nếu bạn cần một enum, hãy xem http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc245030918 –

Trả lời

5

Sử dụng Enum.GetValues:

let allTags = Enum.GetValues(typeof<tags>) 
+0

Nó phải là Enum.GetValues ​​(typeof ). Tôi đã thử điều đó trước đó nhưng không biết cú pháp khác nhau cho typeof. Cảm ơn! – Jared

+3

điều này sẽ không hoạt động vì thẻ không phải là một enum, đó là một công đoàn ... –

+0

mã bạn cung cấp lần đầu ** không ** làm việc với mã Jared được đăng. Nếu một độc giả khác tình cờ gặp phải câu hỏi này, anh ta sẽ nghĩ rằng Enum.GetValues ​​có thể làm việc với các công đoàn, không phải như vậy. Bây giờ bạn đã giải thích rằng tôi đã hoàn nguyên -1 –

2

Để làm cho nó một enum bạn cần phải cung cấp một cách rõ ràng giá trị cho từng trường hợp, nếu không nó là một loại hình công đoàn:

type tags = 
    | ART = 0 
    | N = 1 
    | V = 2 
    | P = 3 
    | NULL= 4 
let allTags = System.Enum.GetValues(typeof<tags>) 
2

Quyền của Robert về cách tạo ra enum thực tế và nhận các trường hợp của nó. Nếu bạn có một loại công đoàn thực sự, bạn có thể nhận được các trường hợp thông qua các chức năng Microsoft.FSharp.Reflection.FSharpType.GetUnionCases.

6

Dưới đây là ví dụ hoàn chỉnh để in thông tin về bất kỳ công đoàn bị phân biệt đối xử nào. Nó cho thấy làm thế nào để có được trường hợp của công đoàn bị phân biệt đối xử và cũng làm thế nào để có được các lĩnh vực (trong trường hợp bạn cần chúng). Việc kê khai chức năng in loại công đoàn phân biệt nhất định:

open System 
open Microsoft.FSharp.Reflection 

let printUnionInfo (typ:Type) = 
    printfn "type %s =" typ.Name 
    // For all discriminated union cases 
    for case in FSharpType.GetUnionCases(typ) do 
    printf " | %s" case.Name 
    let flds = case.GetFields() 
    // If there are any fields, print field infos 
    if flds.Length > 0 then 
     // Concatenate names of types of the fields 
     let args = String.concat " * " [ for fld in flds -> fld.PropertyType.Name ] 
     printf " of %s" args 
    printfn ""  

// Example 
printUnionInfo(typeof<option<int>>) 
+0

Câu hỏi là về enums, không phải là công đoàn phân biệt đối xử. – jason

+2

Việc khai báo kiểu gốc trong bài viết (trước khi bạn chỉnh sửa) là một công đoàn phân biệt đối xử mặc dù ... Enums dĩ nhiên có ích trong F #, nhưng chỉ trong một vài trường hợp. –

+0

Chỉnh sửa duy nhất tôi đã thực hiện cho bài đăng là sửa lỗi đánh máy từ "eumeration" thành "liệt kê". Tôi nghĩ dựa trên chủ đề mà OP luôn dành cho câu hỏi là về enums nhưng giới thiệu sự nhầm lẫn trong việc không xác định chính xác 'thẻ' như là một enum. – jason

1

Bạn có thể sử dụng Enum.GetValues, mà trả về một Array của đối tượng mà sau đó bạn phải downCast các giá trị số nguyên. (Lưu ý:. Tôi đang sử dụng Mono của F # thực hiện; có lẽ mọi thứ đã khác với NET)

Dưới đây là một số chức năng tôi đã viết để có được một danh sách tất cả các giá trị liệt kê và để có được những phút và giá trị tối đa:

open System 

module EnumUtil = 

    /// Return all values for an enumeration type 
    let EnumValues (enumType : Type) : int list = 
     let values = Enum.GetValues enumType 
     let lb = values.GetLowerBound 0 
     let ub = values.GetUpperBound 0 
     [lb .. ub] |> List.map (fun i -> values.GetValue i :?> int) 

    /// Return minimum and maximum values for an enumeration type 
    let EnumValueRange (enumType : Type) : int * int = 
     let values = EnumValues enumType 
     (List.min values), (List.max values) 
0
type Options = 
    | Exit   = 0 
    | CreateAccount = 1 

Console.WriteLine() 
Console.WriteLine("Choose an option:") 
let allOptions = Enum.GetValues(typeof<Options>) 
for option in allOptions do 
    if (option <> null) then 
     Console.WriteLine(sprintf "%d: %s" (option :?> int) (option.ToString())) 
let optionChosen = System.Console.ReadLine() 
Các vấn đề liên quan