1

考虑有moda.d

module moda;

private struct modb {};

并且modb.d

module modb;

private import moda;

并且modmain.d

module modmain;

static import moda;
static import modb;

void main() {
    modb v; // should NOT compile, should it?
}

我不知道为什么,但是在andmoda.modb中都是可见的,而据我所知,它不应该 - 由于被导入为和being 。还是应该?我遇到了 dmd 错误还是我不理解的计划行为?modmainmodbmodastaticmoda.modbprivate

Update1:​​我进行了一些测试,以确定在哪些情况下错误会复制。

第一列是 for import moda,第二列是 for import modb,第三列是用作结构名称的标识符。所有的测试都应该编译失败,但有些可以编译。

图注:D - “导入模块;”,S - “静态导入模块;”,N - 不导入。

D;D;foobar - 由于错误 #2830 而编译

S;D;foobar - 按预期失败

N;D;foobar - 按预期失败

D;S;foobar - 由于错误 #2830 而编译

S;S;foobar - 按预期失败

N;S;foobar - 按预期失败

D;N;foobar - 由于错误 #2830 而编译

S;N;foobar - 按预期失败

N;N;foobar - 按预期失败

D;D;moda - 由于错误 #2830 而编译

S;D;moda - 不应该编译

N;D;moda - 不应该编译

D;S;moda - 由于错误 #2830 而编译

S;S;moda - 不应该编译

N;S;moda - 按预期失败

D;N;moda - 由于错误 #2830 而编译

S;N;moda - 不应该编译

N;N;moda - 按预期失败

D;D;modb - 由于错误 #2830 而编译

S;D;modb - 不应该编译

N;D;modb - 不应该编译

D;S;modb - 由于错误 #2830 而编译

S;S;modb - 不应该编译

N;S;modb - 不应该编译

D;N;modb - 由于错误 #2830 而编译

S;N;modb - 按预期失败

N;N;modb - 按预期失败

似乎如果某个模块的名称与非公开符号相同,则无论保护级别如何,它都会被公开。

4

2 回答 2

1

这是bug# 2830,与静态导入无关。无论您是否使用静态,您都会遇到同样的问题。模块 modb 也与它无关。您可以完全删除它,但仍然会遇到相同的情况。

还有一些关于您的代码的附注:

  1. 放一个; 在结构或类声明的末尾,在 D 中是不必要的。

  2. 进口的私人什么都不做。它们自动是私有的。

  3. 命名符号与模块名称相同可能导致在使用它们时必须提供完整的导入路径。如果您使用多个级别的包,这不是一个大问题(egabc 不会导致您在使用 c 时必须使用完整路径,而 aa 通常需要用作 aa 而不是 a),但如果您只有一个级别的包,它会导致问题。通常,模块名称都是小写的,而类型名称是 PascalCase,变量和函数名称是 camelCase,在这种情况下,您不会遇到太多此类问题(即仅当您拥有单级包并且您有camelCased 符号,只有一个字长)。因此,遵循更典型的 D 命名约定有助于避免该问题。它也往往是其他 D 程序员所期望的,但这显然取决于程序员。它标准库所做的。

于 2012-04-08T01:53:30.963 回答
0

我已经为这种行为填写了一个错误 #7856 。

于 2012-04-08T11:19:53.763 回答