我正在学习union
一点 OCaml,我很困惑。
在 C 中,联合是这样的
union {
int i;
float f;
} x;
x.i = 0x27;
printf ("%f\n", x.f);
那么,OCaml 中的 union 是否具有相同的目的?
让我们举个例子。下面是一个联合定义:
如何像上面的 C 示例一样使用这个联合?
也为这个
是type 'a set
联合定义吗?怎么样type 'a set = 'a list
?为什么?
我正在学习union
一点 OCaml,我很困惑。
在 C 中,联合是这样的
union {
int i;
float f;
} x;
x.i = 0x27;
printf ("%f\n", x.f);
那么,OCaml 中的 union 是否具有相同的目的?
让我们举个例子。下面是一个联合定义:
如何像上面的 C 示例一样使用这个联合?
也为这个
是type 'a set
联合定义吗?怎么样type 'a set = 'a list
?为什么?
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;
};
所以你可以通过访问枚举来询问数字的类型是什么,然后根据枚举的值访问并集的相应字段。当然,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 *)
相当于这样:
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;
}
是
type 'a set
联合定义吗?怎么样type 'a set = 'a list
?为什么?
type 'a set
根本不是一个定义。它只是指定接口。它说这个接口的实现必须定义一个名为的类型set
,它接受一个类型参数。
type 'a set = 'a list
是一个定义,但不是一个受歧视的工会。它只是一个类型别名。那就是说“'a set
只是'a list
'的另一个名称。可区分联合的定义将有一个构造函数作为等号之后的第一件事。构造函数总是以大写字母开头。