- 浏览: 220991 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
dysking:
SWT 和 JFace -
wangyuhfut:
东西不少啊。学习中。。。
一个比较好、中文说明的emacs配置文件 1 -
pacocai:
呵呵!学习,学习~~~不过要说编辑器的话个人更喜欢用VIM,比 ...
一个比较好、中文说明的emacs配置文件 1 -
zhf1zhf2:
这两百多个记起来也不容易啊
英国人是这样背的! -
regex:
试了两次,都是乱码,版本是23.1.1,看来不适合
汉化 Emacs 菜单
模块:
模块声明 多个声明定义
多个声明定义
多个声明定义:
单个声明定义
单个声明定义 多个声明定义
单个声明定义:
属性指示符
导入声明
枚举声明
类声明
接口声明
聚集声明
单个声明
构造函数
析构函数
不变量
单元测试
静态构造函数
静态析构函数
Debug规范
Version规范
Mixin声明
;
模块同源文件是一一对应的。模块名就是去掉路径和扩展名的文件名。
模块自动为它的内容提供一个名字空间。模块跟类有一点相像,不同之处是:
• 每个模块只有一个实例,并且它是静态分配的。
• 模块没有虚函数表。
• 模块不能继承,它们没有父模块,等等。
• 每个文件只有一个模块。• 模块的符号可以导入。
• 模块总是在全局作用域内编译,并且不受周围的特征或其它修饰符影响。
多个模块可以组织成一个结构,叫做“包(packages)”。
模块提供了以下几种担保:
• 模块导入的顺序并不会对语义产生什么影响。
• 一个模块的语义不会被那些导入它的模块所影响。
• 如果一个模块 C 导入了模块 A 和 B,那么任何对 B 的修改都不会隐式地更改在模
块 C 里的跟 A 相独立的代码。
2.1 模块声明
“模块声明”指定了模块的名称和它所属的包。如果不指定,模块名将设定为去掉路径和扩
展名的文件名。
模块声明:
module 模块名 ;
模块名:
标识符
模块名 .标识符
最右面的“标识符”是模块所在的“包”。包在源文件路径中对应于目录名。
如果出现的话,“模块声明”按照语法位于源文件的开头,并且每个源文件只能有一个。
样例:
module c.stdio; // 这是模块 stdio,它位于 c 包中
按照惯例,包和模块名都为 小写。这是因为 包 和 模块名称 同操作系统中的目录名和文件名 一一对应,而许多文件系统不区分大小写。把所有的包和模块名称小写将减少在不同文件系统之间 迁移 项目时的问题。
2 导入声明
与文本的包含文件不同,D 通过使用“导入声明”直接导入符号:
导入声明:
import 导入列表 ;
static import 导入列表 ;
导入列表:
导入
导入绑定
导入 , 导入列表
导入:
模块名
模块别名标识符 = 模块名
导入绑定:
导入 :导入绑定列表
导入绑定列表:
导入绑定
导入绑定 , 导入绑定列表
导入绑定:
标识符
标识符 = 标识符
ModuleAliasIdentifier:
Identifier 2.014
有好几种形式的“导入声明”,从一般的到有细密纹理的(fine-grained)导入。
在“导入声明”里的声明顺序并不重要。
模块名(位于“导入声明”中)必须使用它们所处的那个包的名称来完整修饰。 它们就不
会被认为是相对于那个导入它们的模块。
3 基本导入
最简单的导入形式就是只做列出要被导入的模块:
import std.stdio; // 导入模块 stdio(自 std 包里)
import foo, bar; // 导入杠杆?? foo 和 bar
void main()
{
writefln("hello!\n"); // 调用 std.stdio.writefln
}
基本导入工作原理 就是:首先,在当前名字空间里搜索名字。如果没有找到,那么就到所有导入的模块里去查找。如果在这些导入模块中唯一找到一个,则使用它。
如果在多个导入模块里找到,则就出现错误。
module A;
void foo();
void bar();
module B;
void foo();
void bar();
module C;
import A;
void foo();
void test()
{ foo(); // C.foo() 被调用,它在搜索导入模块之前被找到
bar(); // A.bar() 被调用,因为搜索了导入模块
}
module D;
import A;
import B;
void test()
{ foo(); // 错误,是 A.foo() 还是 B.foo() 呢?
A.foo(); // 正确,调用 A.foo()
B.foo(); // 正确,调用 B.foo()
}
module E;
import A;
import B;
alias B.foo foo;
void test()
{ foo(); // 调用 B.foo()
A.foo(); // 调用 A.foo()
B.foo(); // 调用 B.foo()
}
4 公共导入
默认情况下,导入是“private(私有的)”。即表示,如果 A 导入模块 B,同时 B 又导入模块C,则 C 的名字是不会被搜索的。
一个导入可以特别地声明为“public(公共的)”,这时它会处理成这样:对于带有“导入声明”的模块,它的任何导入模块也会导入那些公共导入的模块。
module A;
void foo() { }
module B;
void bar() { }
module C;
import A;
public import B;
...
foo(); // 调用 A.foo()
bar(); // 调用 B.bar()
module D;
import C;
...
foo(); // 错误,foo() 未定义
bar(); // 正确,调用 B.bar()
5 静态导入
基本导入对于相对没有几个模块和导入的程序很有效。如果存在大量模块导入,则在各种不
同的导入模块里,名字 冲突 就会出现。
防止此种情况发生的一种方式就是使用“静态导入(static imports)”。静态导入要求我们使用带 完整修饰 的名称来 引用 模块名。
static import std.stdio;
void main()
{
writefln("hello!"); // 错误,writefln 未定义
std.stdio.writefln("hello!"); // 正确,writefln 被完全限定
}
6 更名的导入
可以为某个导入给出本地名称;通过这个本地名称,所有对该模块符号的引用都必须进行限
定(be qualified with):
import io = std.stdio;
void main()
{
io.writefln("hello!"); // 正确,调用 std.stdio.writefln
std.stdio.writefln("hello!"); // 错误,std 未定义可能已经覆盖了 std.stdio 名称
writefln("hello!"); // 错误,writefln 未定义
}
更名的导入在处理很长的导入名时很方便。
7 选择性导入
特定的符号可以 特别 地从一个模块被导入,并被绑定到当前名字空间里。
import std.stdio : writefln, foo = writef;
void main()
{
std.stdio.writefln("hello!"); // 错误,std 未定义
writefln("hello!"); // 正确,writefln 被绑定到当前名字空间
writef("world"); // 错误,writefln 未定义
foo("world"); // 正确,调用 std.stdio.writef()
fwritefln(stdout, "abc"); // 错误,writefln 未定义
}
static 不能跟选择性导入一起使用。
8 更名 的且带 选择性 的导入
更名的且带选择性的导入被组合的情形:
import io = std.stdio : foo = writefln;
void main()
{
writefln("bar"); // 错误,writefln 未定义
std.stdio.foo("bar"); // 错误,foo 被绑定到当前名字空间
std.stdio.writefln("bar"); // 错误,std 未定义
foo("bar"); // 错误,foo 被绑定到当前名字空间,
// FQN 不需要
io.writefln("bar"); // 正确,io=std.stdio 将在当前名字空间里的名称 io
// 绑定来引用整个模块
io.foo("bar"); // 错误,foo 被绑定到当前名字空间,
// 而 foo 不是 io 的成员
9 模块作用域运算符
有些时候,有必要重写通常的词法作用域规则以访问被局部名称 掩盖 的名称。可以用 全局作用域 运算符‘.’ 达到这个目的,全局运算符位于标志符之前:
int x;
int foo(int x)
{
if (y)
return x; // 返回的是 foo.x,而非全局的 x
else
return .x; // 返回全局的 x}
前导的‘.’意味着在 模块作用域 级别 查找名称。
10 静态构造 和 析构
静态构造函数 是用来在 main() 之前 运行 的 初始化模块或类的代码。静态析构函数是在 main() 返回 之后 执行的代码,通常用来 释放 系统资源。
在一个模块里可以有 多个 静态构造函数 和 静态析构函数。静态构造函数的是以词法顺序运行的,而静态析构函数 则是以词法 相反 的顺序运行。
10.1 静态构造 的顺序
静态初始化的顺序 隐式 地由模块内的 import 声明的 顺序 决定。每个模块都会在它所依赖的模块 之后 调用自己的静态构造函数。
除了这条规则以外,模块静态构造函数的执行顺序是不定的。
导入声明中的 循环(循环依赖) 是允许的,只要不是两个模块都含有静态构造或析构函数就行。
如果违反这条规则会在运行时产生异常。
10.2 一个模块中 静态构造 的顺序
在模块内部,静态构造 会按照它们出现的 词法 顺序执行。
10.3 静态析构 的顺序
静态析构 将按照与构造函数 相反 的顺序执行。只有当模块的 静态构造函数 成功执行后,才会执行 静态析构函数。
10.4 单元测试的顺序
单元测试是以出现在 模块 里的 词法 顺序运行的。
11 Mixin 声明
Mixin声明:
mixin ( 赋值表达式 ) ;
赋值表达式 必须在编译时求值成一个 常量字符串。该字符串的 文本内容 必须要可编译成一
个 有效 的 多个声明 定义,而且同样地被编译。
。。。
模块声明 多个声明定义
多个声明定义
多个声明定义:
单个声明定义
单个声明定义 多个声明定义
单个声明定义:
属性指示符
导入声明
枚举声明
类声明
接口声明
聚集声明
单个声明
构造函数
析构函数
不变量
单元测试
静态构造函数
静态析构函数
Debug规范
Version规范
Mixin声明
;
模块同源文件是一一对应的。模块名就是去掉路径和扩展名的文件名。
模块自动为它的内容提供一个名字空间。模块跟类有一点相像,不同之处是:
• 每个模块只有一个实例,并且它是静态分配的。
• 模块没有虚函数表。
• 模块不能继承,它们没有父模块,等等。
• 每个文件只有一个模块。• 模块的符号可以导入。
• 模块总是在全局作用域内编译,并且不受周围的特征或其它修饰符影响。
多个模块可以组织成一个结构,叫做“包(packages)”。
模块提供了以下几种担保:
• 模块导入的顺序并不会对语义产生什么影响。
• 一个模块的语义不会被那些导入它的模块所影响。
• 如果一个模块 C 导入了模块 A 和 B,那么任何对 B 的修改都不会隐式地更改在模
块 C 里的跟 A 相独立的代码。
2.1 模块声明
“模块声明”指定了模块的名称和它所属的包。如果不指定,模块名将设定为去掉路径和扩
展名的文件名。
模块声明:
module 模块名 ;
模块名:
标识符
模块名 .标识符
最右面的“标识符”是模块所在的“包”。包在源文件路径中对应于目录名。
如果出现的话,“模块声明”按照语法位于源文件的开头,并且每个源文件只能有一个。
样例:
module c.stdio; // 这是模块 stdio,它位于 c 包中
按照惯例,包和模块名都为 小写。这是因为 包 和 模块名称 同操作系统中的目录名和文件名 一一对应,而许多文件系统不区分大小写。把所有的包和模块名称小写将减少在不同文件系统之间 迁移 项目时的问题。
2 导入声明
与文本的包含文件不同,D 通过使用“导入声明”直接导入符号:
导入声明:
import 导入列表 ;
static import 导入列表 ;
导入列表:
导入
导入绑定
导入 , 导入列表
导入:
模块名
模块别名标识符 = 模块名
导入绑定:
导入 :导入绑定列表
导入绑定列表:
导入绑定
导入绑定 , 导入绑定列表
导入绑定:
标识符
标识符 = 标识符
ModuleAliasIdentifier:
Identifier 2.014
有好几种形式的“导入声明”,从一般的到有细密纹理的(fine-grained)导入。
在“导入声明”里的声明顺序并不重要。
模块名(位于“导入声明”中)必须使用它们所处的那个包的名称来完整修饰。 它们就不
会被认为是相对于那个导入它们的模块。
3 基本导入
最简单的导入形式就是只做列出要被导入的模块:
import std.stdio; // 导入模块 stdio(自 std 包里)
import foo, bar; // 导入杠杆?? foo 和 bar
void main()
{
writefln("hello!\n"); // 调用 std.stdio.writefln
}
基本导入工作原理 就是:首先,在当前名字空间里搜索名字。如果没有找到,那么就到所有导入的模块里去查找。如果在这些导入模块中唯一找到一个,则使用它。
如果在多个导入模块里找到,则就出现错误。
module A;
void foo();
void bar();
module B;
void foo();
void bar();
module C;
import A;
void foo();
void test()
{ foo(); // C.foo() 被调用,它在搜索导入模块之前被找到
bar(); // A.bar() 被调用,因为搜索了导入模块
}
module D;
import A;
import B;
void test()
{ foo(); // 错误,是 A.foo() 还是 B.foo() 呢?
A.foo(); // 正确,调用 A.foo()
B.foo(); // 正确,调用 B.foo()
}
module E;
import A;
import B;
alias B.foo foo;
void test()
{ foo(); // 调用 B.foo()
A.foo(); // 调用 A.foo()
B.foo(); // 调用 B.foo()
}
4 公共导入
默认情况下,导入是“private(私有的)”。即表示,如果 A 导入模块 B,同时 B 又导入模块C,则 C 的名字是不会被搜索的。
一个导入可以特别地声明为“public(公共的)”,这时它会处理成这样:对于带有“导入声明”的模块,它的任何导入模块也会导入那些公共导入的模块。
module A;
void foo() { }
module B;
void bar() { }
module C;
import A;
public import B;
...
foo(); // 调用 A.foo()
bar(); // 调用 B.bar()
module D;
import C;
...
foo(); // 错误,foo() 未定义
bar(); // 正确,调用 B.bar()
5 静态导入
基本导入对于相对没有几个模块和导入的程序很有效。如果存在大量模块导入,则在各种不
同的导入模块里,名字 冲突 就会出现。
防止此种情况发生的一种方式就是使用“静态导入(static imports)”。静态导入要求我们使用带 完整修饰 的名称来 引用 模块名。
static import std.stdio;
void main()
{
writefln("hello!"); // 错误,writefln 未定义
std.stdio.writefln("hello!"); // 正确,writefln 被完全限定
}
6 更名的导入
可以为某个导入给出本地名称;通过这个本地名称,所有对该模块符号的引用都必须进行限
定(be qualified with):
import io = std.stdio;
void main()
{
io.writefln("hello!"); // 正确,调用 std.stdio.writefln
std.stdio.writefln("hello!"); // 错误,std 未定义可能已经覆盖了 std.stdio 名称
writefln("hello!"); // 错误,writefln 未定义
}
更名的导入在处理很长的导入名时很方便。
7 选择性导入
特定的符号可以 特别 地从一个模块被导入,并被绑定到当前名字空间里。
import std.stdio : writefln, foo = writef;
void main()
{
std.stdio.writefln("hello!"); // 错误,std 未定义
writefln("hello!"); // 正确,writefln 被绑定到当前名字空间
writef("world"); // 错误,writefln 未定义
foo("world"); // 正确,调用 std.stdio.writef()
fwritefln(stdout, "abc"); // 错误,writefln 未定义
}
static 不能跟选择性导入一起使用。
8 更名 的且带 选择性 的导入
更名的且带选择性的导入被组合的情形:
import io = std.stdio : foo = writefln;
void main()
{
writefln("bar"); // 错误,writefln 未定义
std.stdio.foo("bar"); // 错误,foo 被绑定到当前名字空间
std.stdio.writefln("bar"); // 错误,std 未定义
foo("bar"); // 错误,foo 被绑定到当前名字空间,
// FQN 不需要
io.writefln("bar"); // 正确,io=std.stdio 将在当前名字空间里的名称 io
// 绑定来引用整个模块
io.foo("bar"); // 错误,foo 被绑定到当前名字空间,
// 而 foo 不是 io 的成员
9 模块作用域运算符
有些时候,有必要重写通常的词法作用域规则以访问被局部名称 掩盖 的名称。可以用 全局作用域 运算符‘.’ 达到这个目的,全局运算符位于标志符之前:
int x;
int foo(int x)
{
if (y)
return x; // 返回的是 foo.x,而非全局的 x
else
return .x; // 返回全局的 x}
前导的‘.’意味着在 模块作用域 级别 查找名称。
10 静态构造 和 析构
静态构造函数 是用来在 main() 之前 运行 的 初始化模块或类的代码。静态析构函数是在 main() 返回 之后 执行的代码,通常用来 释放 系统资源。
在一个模块里可以有 多个 静态构造函数 和 静态析构函数。静态构造函数的是以词法顺序运行的,而静态析构函数 则是以词法 相反 的顺序运行。
10.1 静态构造 的顺序
静态初始化的顺序 隐式 地由模块内的 import 声明的 顺序 决定。每个模块都会在它所依赖的模块 之后 调用自己的静态构造函数。
除了这条规则以外,模块静态构造函数的执行顺序是不定的。
导入声明中的 循环(循环依赖) 是允许的,只要不是两个模块都含有静态构造或析构函数就行。
如果违反这条规则会在运行时产生异常。
10.2 一个模块中 静态构造 的顺序
在模块内部,静态构造 会按照它们出现的 词法 顺序执行。
10.3 静态析构 的顺序
静态析构 将按照与构造函数 相反 的顺序执行。只有当模块的 静态构造函数 成功执行后,才会执行 静态析构函数。
10.4 单元测试的顺序
单元测试是以出现在 模块 里的 词法 顺序运行的。
11 Mixin 声明
Mixin声明:
mixin ( 赋值表达式 ) ;
赋值表达式 必须在编译时求值成一个 常量字符串。该字符串的 文本内容 必须要可编译成一
个 有效 的 多个声明 定义,而且同样地被编译。
。。。
发表评论
-
土耳其文《d编程》range 翻译 一
2011-11-15 02:01 1507Ranges 范围 Ranges are an abstra ... -
土耳其文《d编程》range 翻译 二
2011-11-15 01:59 1006As you can see, that output doe ... -
d2 range 和 标准C++中的Iterator(迭代器)简介
2011-05-07 12:59 2117原文: http://hi.baidu.com/c ... -
三访安德烈Alexandrescu(第2部)
2010-08-20 12:53 1422Google翻译哦 面试------> 应翻成 访谈 ... -
三访安德烈Alexandrescu(第一部分)
2010-08-20 12:43 1349google翻译哦 Interview with Andre ... -
Garden Editor project 日记 之二 10.16 ---
2009-10-16 02:39 02009.10.16 T[new] misgivings ... -
Garden Editor project 日记 之一 09.09.25 --- 10.15
2009-09-24 22:56 0kill two birds with one stone, ... -
template metaprogramming 9
2009-09-09 16:08 1169原文:https://docs.google.co ... -
Floating Point in D (2.030 新)
2009-05-12 23:27 20485.17 23:50 更新 5.16 20:30 翻译更 ... -
Migrating to Shared (2.030 新)
2009-05-12 23:03 11545.19 0:10 更新(完成) ... -
D 2.0 的gc
2008-12-04 19:53 1251http://lucifer1982.wordpress.co ... -
垃圾回收 2.014
2008-06-10 07:20 983无版本差异 D 是一种全面采用垃圾回收(Garbage Co ... -
类 class 2.014
2008-06-09 22:51 1085D 的面向对象的特性都来源于类。类层次里的顶层是 Object ... -
接 口 2.014
2008-06-09 22:51 843接口声明: interface 标 ... -
C 语言接口 2.014
2008-06-09 22:50 1029D 的设计就是要在目标系统上能够很好地符合于 C 编译器。D ... -
Traits 特征 2.014
2008-06-07 11:25 12466.14 翻译 (d语言的反 ... -
常量和不变量 Const and Invariant 2.014
2008-06-07 11:22 1312请参考: D 2.0 Const/Final/Invarian ... -
词法 2.014
2008-06-07 10:22 1501在 D 中,词法分析独立于语法分析和语义分析。词法分析器是将源 ... -
枚 举 2.014
2008-06-07 08:41 1155枚举声明: enum 枚举标记 枚举体 enum 枚举体 en ... -
函 数 2 (2.014)
2008-06-07 08:22 10327 嵌套函数 函数可以被 ...
相关推荐
2. **材质要求**: - 钢筋必须具备出厂质量证明书,并经过复检合格,确保其力学性能满足设计要求。 3. **施工机具**: - 需要的工具包括钢筋钩子、撬棍、网筋板子、绑扎架、钢丝刷、钢筋运输车、石笔、墨斗、尺子...
尽管土壤有机质(SOM)占土壤主体的一小部分。 然而,它是土壤生态系统以及碳全球循环的最重要组成部分。... 表土中的SOC的块金,范围和底线分别等于0.002、0.036和0.044,底土中的SOC的块金,范围和基石分别等于0.014
2. **材质要求**: - 钢筋必须有出厂质量证明书,并经过复试检验,确保其力学性能满足设计要求。 3. **施工机具**: - 包括钢筋钩子、撬棍、网筋板子、绑扎架、钢丝刷、钢筋运输车、石笔、墨斗、尺子等,这些工具...
2. **Software Component (SW-C)**: SW-C是AUTOSAR系统中的基本构建块,代表了独立的软件功能。它们定义了与硬件无关的功能,并可以通过接口与其他组件通信。文档中可能包含了关于SW-C的建模规范,如其接口定义、...
使用WinAC CAN Basic Driver可以让用户实现PLC程序控制下的CAN通信,它包含有CAN发送和接收函数块,即按照OSI模型的第二层(数据链路层)实现的功能。文档强调了该驱动程序支持的硬件接口,例如Microbox IPC427B/C板...
2. **Velocity 模板语言(VTL)**: - VTL 提供了一系列指令,如 `#set`、`#if`、`#foreach` 等,用于控制流程和数据处理。 - `${}` 用于输出变量,`##` 用于注释,`#end` 结束一个块等,这些是 VTL 的基础语法...
2. multiCCL_m.exe 内存特征码专用版 3. multiCCL_inj.exe 注入代码块内存定位专用版 4. memtest.exe 用作内存定位时加载dll或运行exe或向目标进程注入的辅助程序 (为了防止主程序被杀毒软件Kill,用了远程...
2. multiCCL_m.exe 内存特征码专用版 3. multiCCL_inj.exe 注入代码块内存定位专用版 4. memtest.exe 用作内存定位时加载dll或运行exe或向目标进程注入的辅助程序 (为了防止主程序被杀毒软件Kill,用了远程...
2. **泛型**:C#2005引入了泛型,它允许开发者创建可重用的类型安全的数据结构,如集合。D028可能详述泛型的定义、约束及其在代码中的应用。 3. **Lambda表达式和Linq**:D014和D018可能涵盖了C#2005引入的Lambda...
2. **进销存(Inventory Management)**:进销存系统是企业管理的核心部分,用于跟踪图书的采购、销售和库存情况。它包括采购订单管理、销售订单管理、库存盘点、库存预警等功能,确保库存水平适中,避免过度库存和...