什么是OCaml中的`union`,真的

Jac*_*ale 3 ocaml functional-programming

我正在学习unionOCaml 的一点,我很困惑.


在C中,联合就是这样的

union {
    int i;
    float f;
} x;
x.i = 0x27;
printf ("%f\n", x.f);
Run Code Online (Sandbox Code Playgroud)

那么,OCaml中的联合服务于同一目的吗?

我们来举个例子吧.以下是联合定义:

在此输入图像描述

我如何像上面的C示例一样使用这个联合?


也是为了这一个

在此输入图像描述

type 'a set一个联合定义?怎么样type 'a set = 'a list?为什么?

sep*_*p2k 8

OCaml中的一个有区别的联盟就像一个C联合和一个枚举.所以你的一个number类型的例子可以在C中表示如下:

enum number_tag {
    ZERO, INTEGER, REAL
};

union number_value {
    int i; /* Only access this if tag is INTEGER */
    float f; /* Only access this if tag is REAL */
};

struct number {
    enum number_tag tag;
    union number_value value;
};
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过访问枚举来询问数字的类型,然后根据枚举的值访问联合的相应字段.当然C不会停止访问联盟的错误字段.

另一方面,OCaml消除了访问错误字段的可能性.由于您只能通过模式匹配来访问值,因此您知道始终拥有正确的类型.

number在OCaml 中,类型值的模式匹配将如下所示:

match value_of_type_number with
| Zero ->
    (* Handle the case that the number is Zero *)
| Integer i ->
    (* Handle the case that the number is an Integer with the value i *)
| Float f ->
    (* Handle the case that the number is a Float with the value f *)
Run Code Online (Sandbox Code Playgroud)

相当于这个:

switch(value_of_type_number.tag) {
case ZERO:
    /* Handle the case that the number is Zero */
    break;
case INTEGER:
    int i = value_of_type_number.value.i;
    /* Handle the case that the number is an Integer with the value i */
    break;
case FLOAT:
    float f = value_of_type_number.value.f;
    /* Handle the case that the number is a Float with the value f */
    break;
}
Run Code Online (Sandbox Code Playgroud)

type 'a set一个联合定义?怎么样type 'a set = 'a list?为什么?

type 'a set根本不是一个定义.它只是指定接口.它说这个接口的实现必须定义一个名为的类型set,它接受一个类型参数.

type 'a set = 'a list是一个定义,但不是一个受歧视的联盟.它只是一个类型别名.也就是它说" 'a set只是'a list'的另一个名称.一个有区别的联盟的定义会有一个构造函数作为等号后的第一个东西.构造函数总是以大写字母开头.