简体   繁体   English

f# 中的discriminated unions (pure) 是如何实现的

[英]how is discriminated unions (pure) implemented in f#

I wonder if they are simply using a number to represent each cases, or they will be compiled to control flows (if statements) that helps decide the matter我想知道他们是否只是简单地使用一个数字来表示每个案例,或者它们将被编译以控制有助于决定问题的流程(if 语句)

pure means the cases aren't of any data types pure 表示案例不是任何数据类型

I tried looking for answers on stack overflow but I didn't find any我尝试寻找有关堆栈溢出的答案,但没有找到任何答案

In general yes, each case is a number (called Tag in the implementation).一般来说是的,每个案例都是一个数字(在实现中称为标签)。 It's easy to figure out how some things are realized in F# by decompiling F# assembly to C#.通过将F#汇编反编译为C#,很容易搞清楚F#中有些东西是如何实现的。

Eg例如

Union type defined like this:联合类型定义如下:

type UnionType = This | That of int

Decompiles to C# like this (I cut out interface implementations at the bottom as it is pretty lengthy, you can easily repeat this process yourself):像这样反编译成C#(我在底部删掉了接口实现,因为它很长,你可以很容易地自己重复这个过程):

[Serializable]
[StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)]
[DebuggerDisplay("{__DebugDisplay(),nq}")]
[CompilationMapping(SourceConstructFlags.SumType)]
public abstract class UnionType : IEquatable<UnionType>, IStructuralEquatable, IComparable<UnionType>, IComparable, IStructuralComparable
{
    public static class Tags
    {
        public const int This = 0;

        public const int That = 1;
    }

    [Serializable]
    [SpecialName]
    [DebuggerTypeProxy(typeof(_This@DebugTypeProxy))]
    [DebuggerDisplay("{__DebugDisplay(),nq}")]
    internal class _This : UnionType
    {
        [CompilerGenerated]
        [DebuggerNonUserCode]
        internal _This()
        {
        }
    }

    [Serializable]
    [SpecialName]
    [DebuggerTypeProxy(typeof(That@DebugTypeProxy))]
    [DebuggerDisplay("{__DebugDisplay(),nq}")]
    public class That : UnionType
    {
        [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
        [CompilerGenerated]
        [DebuggerNonUserCode]
        internal readonly int item;

        [CompilationMapping(SourceConstructFlags.Field, 1, 0)]
        [CompilerGenerated]
        [DebuggerNonUserCode]
        public int Item
        {
            [CompilerGenerated]
            [DebuggerNonUserCode]
            get
            {
                return item;
            }
        }

        [CompilerGenerated]
        [DebuggerNonUserCode]
        internal That(int item)
        {
            this.item = item;
        }
    }

    [SpecialName]
    internal class _This@DebugTypeProxy
    {
        [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
        [CompilerGenerated]
        [DebuggerNonUserCode]
        internal _This _obj;

        [CompilerGenerated]
        [DebuggerNonUserCode]
        public _This@DebugTypeProxy(_This obj)
        {
            _obj = obj;
        }
    }

    [SpecialName]
    internal class That@DebugTypeProxy
    {
        [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
        [CompilerGenerated]
        [DebuggerNonUserCode]
        internal That _obj;

        [CompilationMapping(SourceConstructFlags.Field, 1, 0)]
        [CompilerGenerated]
        [DebuggerNonUserCode]
        public int Item
        {
            [CompilerGenerated]
            [DebuggerNonUserCode]
            get
            {
                return _obj.item;
            }
        }

        [CompilerGenerated]
        [DebuggerNonUserCode]
        public That@DebugTypeProxy(That obj)
        {
            _obj = obj;
        }
    }

    [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
    [CompilerGenerated]
    [DebuggerNonUserCode]
    internal static readonly UnionType _unique_This = new _This();

    [CompilerGenerated]
    [DebuggerNonUserCode]
    [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
    public int Tag
    {
        [CompilerGenerated]
        [DebuggerNonUserCode]
        get
        {
            return (this is That) ? 1 : 0;
        }
    }

    [CompilerGenerated]
    [DebuggerNonUserCode]
    [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
    public static UnionType This
    {
        [CompilationMapping(SourceConstructFlags.UnionCase, 0)]
        get
        {
            return _unique_This;
        }
    }

    [CompilerGenerated]
    [DebuggerNonUserCode]
    [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
    public bool IsThis
    {
        [CompilerGenerated]
        [DebuggerNonUserCode]
        get
        {
            return this is _This;
        }
    }

    [CompilerGenerated]
    [DebuggerNonUserCode]
    [DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
    public bool IsThat
    {
        [CompilerGenerated]
        [DebuggerNonUserCode]
        get
        {
            return this is That;
        }
    }

    [CompilerGenerated]
    [DebuggerNonUserCode]
    internal UnionType()
    {
    }

    [CompilationMapping(SourceConstructFlags.UnionCase, 1)]
    public static UnionType NewThat(int item)
    {
        return new That(item);
    }

    /* cut out members including interface implementations */

}

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

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