F#记录:具有相同名称的字段

时间:2011-03-08 10:42:59

标签: f#

请考虑以下记录定义:

type A = { F1 : int; F2 : int }
type B = { F1 : int; F3 : int } 

// error FS0656: This record contains fields from inconsistent types   
let a1 = { F1 = 1; F2 = 2 } 

// this works
let a2 = { A.F1 = 1; F2 = 2 }

我不明白,为什么a1会导致错误。

我能找到为什么你必须以a2方式做的所有例子都假设A和B中的所有字段名都有相同的名字 - 这当然是不明确的,但A和B不应该是在拥有至少一个不同的领域时可以区分吗?

也许这就是F#对此进行评估的方式,将类型名称添加到第一个字段当然没什么大不了的,但我只是好奇。

编辑: 感谢您的回答让我注意到一些相当奇怪的事情:当我第一次评估它时,整个片段都有效(ALT +在VS 2010中输入)。

当我第二次尝试评估时,我收到错误。

如果没有人可以重现这个,我的VS安装可能会被淹没......

EDIT2(好吧,在这里创建一个帐户的时间,对不起编辑) 感谢wmeyer(以及其他所有人)花时间查看问题并让我意识到我对FSI的工作方式的误解。现在全部清理完了!

3 个答案:

答案 0 :(得分:6)

我认为您的装置不会被塞住。

第二次评估时代码不起作用是有道理的。旧类型AB仍然存在,它们只是shadowed 另一方面,字段名称永远不会被遮蔽。 (否则你在两个不同的记录中永远不会有相同的字段名称。)
“所有可能记录的联合”(参见Massif的回答)现在有多个元素:旧的(阴影)A和新的A

要解决此问题,您可以在两次运行之间使用F#Interactive上下文菜单中的“重置会话”。或者将代码包装在一个模块中(然后旧的记录类型既不可访问也不在范围内)。

答案 1 :(得分:5)

刚刚用fsi检查过,这段代码可以正常工作

type A = { F1 : int; F2 : int }
type B = { F1 : int; F3 : int } 
let a1 = { F1 = 1; F2 = 2 } 

也许你的帖子中没有提到其他导致这种含糊不清的内容?

答案 2 :(得分:3)

确实,听起来应该有效 - 来自the spec

  

如果field-labeli不是单一的   标识符或初始类型是   变量类型,然后是字段标签   通过执行字段标签解决   决议(见§14.1)   field-labeli,产生一组   FSeti。这个的每个要素   set有相应的记录类型,   产生一组记录类型   RSeti。所有RSeti的交集   必须给出单个记录类型R,和   每个字段然后解析为   R中的相应字段。

这意味着只要包含这些字段标识符的所有可能记录的并集解析为只有一种记录类型,那么它就是合法的。你使用什么编译器?