Switch 语句
switch 语句依照 switch 表达式的值来选择一条 case 语句执行。Switch语句: switch ( 表达式 ) 语句块 Case语句: case 表达式列表 : 语句 Default语句: default: 语句
SwitchStatement: switch ( Expression ) BlockStatement CaseStatement: case ExpressionList : Statement DefaultStatement: default: Statement表达式 被计算. 结果的类型 T 必须是整数类型或者 char[] 或者 wchar[] 。所得结果同各个 case 表达式进行比较。如果存在匹配,就转而执行相应的 case 语句。
case 表达式,也就是 表达式列表 ,是由逗号分隔的表达式的列表。
如果没有 case 表达式能够匹配,并且存在 default 语句,就转去执行 default 语句。
如果没有 case 表达式能够匹配,并且不存在 default 语句,就会抛出 SwitchError 异常。之所以这么做,是为了捕获一些常见的错误,如为枚举添加了新值却忘记了为这个值提供对应的 case 语句。这同 C 和 C++ 不太一样。
case 表达式必须都是常量值或数组,并且必须能隐式地转换为 switch 表达式 的类型 T。
Case 表达式的值必须互不相同。不能有多于一个的 default 语句。
与 switch 相关联的 case 语句和 default 语句可以在语句块中嵌套;它们不必非要位于最外层的块中。例如,下面是合法的:
switch (i)
{
case 1:
{
case 2:
}
break;
}
同在 C 和 C++ 中一样,case 语句会顺序执行后面的 case 子句。break 语句将退出 switch 语句块。例如: switch (i)
{
case 1:
x = 3;
case 2:
x = 4;
break;
case 3,4,5:
x = 5;
break;
}
如果 i 等于 1,x 将等于 4 。
注意:同 C 和 C++ 不同的是,可以在 switch 表达式中使用字符串。例如:
char[] name;
...
switch (name)
{
case "fred":
case "sally":
...
}
对于如命令行选项处理这样的应用来说,采用这种语法的代码更直接,更清晰并且不易出错。ascii 和 wchar 都可以使用。
实现注意:编译器的代码生成程序可以认为 case 语句已经按照使用的频率排序,频率高的排在最前面,频率低的排在最后。尽管这不会影响程序的正确性,但对于提高性能来说是有益的。
Continue 语句
continue 中止它所在的循环语句的此次迭代,并直接开始下次迭代。Continue语句: continue; continue 标志符 ;
ContinueStatement: continue; continue Identifier ;continue 执行它所在最内层的 while、for 或者do 语句的下次迭代。
如果 continue i后跟有 标志符 ,则该 标志符 必须是它所在的 while、for 或者 do 语句外的标号,continue 会执行所在循环的下次迭代。如果不存在那样的语句,就是错误。
所有的被跳过的 finally 子句都会执行,同时会释放所有的被跳过的同步对象。(译注:目前未实现。)
注意:如果 finally 子句中有 return、throw 或者 goto 到 finally 子句之外的这样的动作,continue 的目标永远也无法达到。
Break 语句
break 退出它所在的语句。Break语句: break; break 标志符 ;
BreakStatement: break; break Identifier ;break 退出它所在最内层的 while、for、do 或者 switch 语句,并在该语句之后恢复执行。
如果 break 后跟有 标志符 ,则该 标志符 必须是它所在的 while、for、do 或者 switch 语句外的标号,break 会退出那条语句。如果不存在那样的语句,就是错误。
所有的被跳过的 finally 子句都会执行,同时会释放所有的被跳过的同步对象。(译注:目前未实现。)
注意:如果 finally 子句中有 return、throw 或者 goto 到 finally 子句之外的这样的动作,break 的目标永远也无法达到。
Return 语句
return 语句的作用是推出当前的函数并提供一个返回值。Return语句: return; return 表达式 ;
ReturnStatement: return; return Expression ;如果函数指定了非 void 的返回类型,就必须给出 表达式 。表达式 会被隐式地转换为函数的返回类型。
如果函数指定了非 void 的返回类型,就必须提供至少一个 return 语句。
就算函数的返回类形是 void,也可以有 表达式 存在。表达式 会被计算,但是什么也不会返回。
在函数真正返回之前,会执行所有外围的 finally 子句,并会释放外围的所有同步对象。
如果外围的 finally 子句中有 return、goto 或者 throw 的话,函数就不会正常的返回。
如果存在后验条件(参见契约式编程),则在计算 表达式 之后执行该后验条件,然后函数返回。
Goto 语句
goto 会跳转到以 标志符 为标号的语句处运行。Goto语句: goto 标志符 ; goto default ; goto case ; goto case 表达式 ;
GotoStatement: goto Identifier ; goto default ; goto case ; goto case Expression ;第二种形式,goto default; ,会跳转到最内层 Switch语句 中的 Default语句 处。
第三种形式,goto case; ,会跳转到最内层 Switch语句 中的下一个 Case语句 处。
第四种形式,goto case 表达式; ,会跳转到包含带有 表达式 的 Case语句 的最内层 Switch语句 中那个 Case语句 处。
所有的被跳过的 finally 子句都会执行,同时会释放所有的被跳过的同步互斥体。(译注:目前未实现。)
使用 goto 来跳过初始化是非法的。
With 语句
with 语句用来简化对同一个对象的重复引用。With语句: with ( 表达式 ) 语句块 with ( 模板实例 ) 语句块
WithStatement: with ( Expression ) BlockStatement with ( TemplateInstance ) BlockStatement表达式 的结果是对类实例或者结构的引用。在 with 的过程体内,所有的标志符符号都将在那个类引用的名字空间内查找。with 语句:
with (expression)
{
...
ident;
}
在语义上等价于: {
Object tmp;
tmp = expression;
...
tmp.ident;
}
注意表达式只会计算一次。with 语句不会改变 this 或 super 引用的对象。
Synchronize 语句
synchronize 语句用来在多线程情况下同步临界区内的语句。Synchronize语句: synchronized 语句 synchronized ( 表达式 ) 语句
SynchronizeStatement: synchronized Statement synchronized ( Expression ) Statementsynchronized 每次只允许一个线程执行 语句。
在 synchronized (表达式) 这种用法中,表达式 的结果应为对一个 Object 对象的引用,它每次只允许在一个线程中的那个 Object 执行 语句。
当 语句 遇到异常、goto 或者 return 中止时,同步中止。
示例:
synchronized { ... }
这实现一个标准的临界区。
Try 语句
异常处理由 try-catch-finally 语句完成。Try语句: try 语句块 多个Catch try 语句块 Catches finally 语句块 try 语句块 finally 语句块 多个Catch: LastCatch Catch Catch 多个Catch LastCatch: catch 语句块 Catch: catch ( 参数 ) 语句块
TryStatement: try BlockStatement Catches try BlockStatement Catches finally BlockStatement try BlockStatement finally BlockStatement Catches: LastCatch Catch Catch Catches LastCatch: catch BlockStatement Catch: catch ( Parameter ) BlockStatementParameter 声明了类型为 T 的变量 v ,其中 T 是 Object 或者从 Object 派生而来。如果 T 与 throw 表达式类型相同或者是 throw 表达式的基类,v 被初始化为 throw 表达式。如果异常对象是 T 型或者从 T 派生的,catch 子句将被执行。
如果只给出了类型 T 而没有给出变量 v ,catch 子句仍将被执行。
如果有类型为 T1 的 Catch 参数 掩盖了后面的类型为 T2 的 Catch ,也就是说如果 T1 同 T2 类型相同或者是 T2 的基类,就是错误。
LastCatch 捕获所有的异常。
Throw 语句
抛出一个异常。Throw语句: throw 表达式 ;
ThrowStatement: throw Expression ;表达式 被计算,结果必须是 Object 引用类型。该 Object 的引用被作为异常抛出。
Volatile 语句
没有什么代码活动能跨越 volatile 语句的边界。Volatile语句: volatile 语句
VolatileStatement: volatile Statement语句 被计算。在 语句 之前的所有内存写操作都保证在 语句 中或其后的内存读操作之前完成。在 语句 之后的所有内存读操作都保证在 语句 中或其前的所有内存写完成之后执行。
volatile 语句不能保证原子性。如果要保证原子性,应该使用 synchronized 语句。
Asm 语句
asm 语句用来支持内联汇编: Asm语句:
asm { }
asm { Asm指令列表 }
Asm指令列表:
Asm指令 ;
Asm指令 ; Asm指令列表 AsmStatement:
asm { }
asm { AsmInstructionList }
AsmInstructionList:
AsmInstruction ;
AsmInstruction ; AsmInstructionList
asm 语句使你可以直接使用汇编语言指令。这样不必费力地采用外部的汇编程序就可以获得对CPU特殊特征的直接访问能力。D 编译器会替你管理函数调用约定、堆栈设置等等恼人的事情。
指令的格式,当然,高度依赖于目标CPU的指令集,所以是由 实现定义 的。但是,格式需要遵循下述约定:
- 必须使用同 D 语言相同的记号。
- 注释的形式必须同 D 语言的相通。
- Asm 指令以‘;’结尾,而不是以行尾结尾。
例如,对于 Intel Pentium 处理器:
int x = 3;
asm
{
mov EAX,x; // 将 x 载入寄存器 EAX
}
内联汇编可以用来直接访问硬件: int gethardware()
{
asm
{
mov EAX, dword ptr 0x1234;
}
}
对于某些 D 实现,如将 D 翻译为 C 的翻译器来说,内联汇编没有什么意义,也就不需要实现它。version 语句可以用来应付这种情况: version (InlineAsm)
{
asm
{
...
}
}
else
{
... 不采用内联汇编的方式 ...
}
本文详细介绍了D语言中的多种语句,如Switch、Continue、Break等语句。以Switch语句为例,阐述了其case表达式规则、异常处理等,还提及与C和C++的不同。同时对其他语句的使用规则、注意事项等进行了说明,包括跳转、同步、异常处理等方面。

被折叠的 条评论
为什么被折叠?



