Hyperlinks
激活模块B中的任何带注释的export子句会使模块B未知导入的函数f。有帮助吗?
答案 0 :(得分:0)
错误消息有点混乱,或者至少是微妙的。对两个export K ...
声明中的任何一个取消注释都会产生以下两个错误:
This export set is not consistent: K
Raised while checking export set K: unresolved identifier: f
让我解释一下。我将重点介绍export K provides k
声明;另一个是相似的。
通过声明导出集,模块可以将其声明的子集提供给模块的进口商。 provides
子句将声明的“签名”放入导出集中,而reveals
子句将声明的“签名”和“正文”放入导出集中。对于函数,声明的“签名”包括函数的类型签名以及函数的规范。因此,示例中的provides k
子句实质上是说要导出k
声明的以下部分:
function k (x:int):int requires f(x) == 0
此处要注意的相关事项是,声明的这一部分还提到了f
。 (对于使用reveal k
的导出声明也是如此。)
导出集必须自洽。这意味着在导出的声明中提及的所有内容(更确切地说,在导出的声明中的导出部分-“签名”或“签名+正文”)必须分别有意义。特别是,这意味着在导出部分中提到的每个符号(此处是在f
的前提下提到k
)也必须是导出集的一部分。
因此,问题在于您尝试导出k
,而不是f
。如果在模块{{1}中声明了f
,您将知道该怎么做:只需将B
添加到导出集的f
子句中。但是对于您来说,provides
是在模块f
中声明的,而不是在A
中声明的。这似乎是一个问题,因为模块B
中的导出集仅允许导出B
中定义的符号。
问题有一个简单的解决方案。为了更清楚地说明这一点,让我临时更改一下模块B
:
B
在这里,我仅导入module B {
import A = A`S
export K provides k
function k (x:int):int requires A.f(x) == 0 {x*2}
}
(而不是A`S
),我明确显示了A`M
(即A`S
)的本地名称,省略了A
关键字。由于我省略了opened
关键字,因此我还必须限定opened
的规范中对f
的提及(写k
而不只是A.f
)。
好的,在此模块f
中,导出集B
仍然不一致,因为它尝试提供K
而没有提供k
。更准确地说,第二条错误消息现在表明A.f
未解决。很好,因为A
中声明了(本地名称)A
,这意味着我们可以导出它。要解决此问题,只需将B
添加到导出集:
provides A
这使导出集export K provides k, A
保持一致,因为K
声明的(“签名”部分中提到的每个符号都是可见的)。 k
不必直接导出K
,因为f
提到{{1}是f
的成员,而.f
是A
的成员。导出。
让我们以四个步骤回到您的示例。
第一步,让我们更改A
声明,以同时导入import
和A
的两个导出集:
S
在这里,我仍在明确显示本地名称M
。
第二步,让我们重新添加import A = A`{S,M}
关键字:
A
这使得可以将导入的声明引用为合格的(如opened
)或不合格的(仅import opened A = A`{S,M}
)。
第三步,我们利用以下事实:在A.f
中,我们可以将f
称为不合格:
B
作为第四步,也是最后一步,请回到示例中,在f
声明中省略显式的本地名称function k (x:int):int requires f(x) == 0 {x*2}
。默认本地名称与要导入的模块相同,即A
。现在,我们有以下无错误程序:
import
我希望这会有所帮助。
Rustan