-unittest
單元測試.
in,out,invariant
沒有-release
.
單元測試/合同用於程序正確性
.
模板只特化實際使用類型
.
void swap(T)(ref T lhs, ref T rhs) {
T temp = lhs;
lhs = rhs;
rhs = temp;
}
unittest {
auto a = 'x';
auto b = 'y';
swap(a, b);
assert(a == 'y');
assert(b == 'x');
}
void swap(T : uint)(ref T lhs, ref T rhs) {
lhs ^= rhs;
rhs ^= lhs;
lhs ^= rh; // TYPO!
}
void main() {
}
原來認爲^
比臨時
的慢.但相反,現代微控器這種方法更慢.
unittest {
uint i = 42;
uint j = 7;
swap(i, j);
assert(i == 7);
assert(j == 42);
}
//單元測試,發現錯誤
d
的條件編譯:
debug
version
static if,c++已有
is expression
__traits
開發期間,-調試
很有用.
debug a_conditionally_compiled_expression;
debug {
// ... 條件編譯代碼...
} else {
// ... 否則編譯代碼 ...
}
調試
size_t binarySearch(const int[] values, in int value) {
writefln("searching %s among %s", value, values);
if (values.length == 0) {
writefln("找不到%s", value);
return size_t.max;
}
immutable midPoint = values.length / 2;
writefln("考慮%s索引", midPoint);
if (value == values[midPoint]) {
writefln("found %s at index %s", value, midPoint);
return midPoint;
} else if (value < values[midPoint]) {
writefln("必在前半");
return binarySearch(values[0 .. midPoint], value);
} else {
writefln("必在後半");
return binarySearch(values[midPoint + 1 .. $], value);
}
}
在前面加上debug
,這樣下次還可用.
debug writefln("%s not found", value);
dmd deneme.d -ofdeneme -w -debug
就可搞定了
只輸出我想要的:
debug(binarySearch) writefln("%s not found", value);
dmd deneme.d -ofdeneme -w -debug=binarySearch
這樣只調試這種塊.
塊也可以
debug(binarySearch) {
// ...
}
dmd deneme.d -w -debug=binarySearch -debug=stackContainer
多個調試塊.
可以逐漸增加調試級:
debug import std.stdio;
void myFunction(string fileName, int[] values) {
debug(1) writeln("entered myFunction");
//1級.
debug(2) {//2級
writeln("the arguments:");
writeln(" file name: ", fileName);
foreach (i, value; values) {
writefln(" %4s: %s", i, value);
}
}
// ...實現函數...
}
void main() {
myFunction("deneme.txt", [ 10, 4, 100 ]);
}
//---
$ dmd deneme.d -w -debug=1
$ ./deneme
entered myFunction
將打印級數小的,級越大,越詳細
version(tag) 和 version(level)
,類似debug
.
version(testRelease) /* ... an expression ... */;
version(schoolRelease) {
//此版本與學校發佈相關
} else {
// ... 否則編譯代碼...
}
version(1) aVariable = 5;
version(2) {
// ... 2版本特徵 ...
}
$ dmd deneme.d -w -version=record -version=precise_calculation
定義多個版本
完整預定義版本標誌
none(禁用)
,all(允許)
代碼塊.
version(Windows) {
immutable newline = "\r\n";
} else version(Posix) {
immutable newline = "\n";
} else {
static assert(0, "不支持 OS");
}
用於確定系統的換行符.
import std.stdio;
debug(everything) {
debug = binarySearch;
debug = stackContainer;
version = testRelease;
version = schoolRelease;
}
void main() {
debug(binarySearch) writeln("binarySearch is active");
debug(stackContainer) writeln("stackContainer is active");
version(testRelease) writeln("testRelease is active");
version(schoolRelease) writeln("schoolRelease is active");
}
這些debug
與version
變量就像個集
一樣,加進去.只要有其中一個,就可以調試了.就像調試集
/版本集
.
命令如下dmd deneme.d -w -debug=everything
.
static if
,編譯時條件判斷,只要是編譯時已知的東西都可以用它.用來決定如何生成代碼.邏輯表達式經常可以利用is
和雙下劃線trait
.
可在模塊域
或類,構,模板
中出現static if
.也可以有if
語句.
簡單例子:
import std.stdio;
struct MyType(T) {
static if (is (T == float)) {
alias ResultType = double;
} else static if (is (T == double)) {
alias ResultType = real;
} else {//
static assert(false, T.stringof ~ " is not supported");
}
ResultType doWork() {
writefln("The return type for %s is %s.",
T.stringof, ResultType.stringof);
ResultType result;
// ...
return result;
}
}
void main() {
auto f = MyType!float();
f.doWork();
auto d = MyType!double();
d.doWork();
}
只能用於浮
與雙精
,返回類型取決於其中一個.
注意,編譯時的比較都必須寫static if
.如果不寫static
,將把剩下的if
塊插入進去.就與本意不一樣了.
static assert
,編譯時斷定是否滿足條件.如爲假,程序直接退出.可出現在程序的任何域
中.
如上面程序,auto i = MyType!int();
,將會導致static assert "int is not supported"
.不支持.
如算法只適用於特定情況:
T myAlgorithm(T)(T value) {
static assert((T.sizeof % 4) == 0);
//要求T的大小是4的整數倍
// ...
}
調用時,如果爲char
,就會失敗.
這樣,避免使用錯誤的類型,而產生可能的錯誤
了.
__traits
提供編譯時類型和表達式
的信息.
編譯器收集的.可以這樣__traits(keyword, parameters)
關鍵詞爲要查的信息,參數爲(類型/表達式).這些信息對模板非常有用
.
static if (__traits(isArithmetic, T)) {
// ... 算術類型...
} else {
// ... 不是 ...
}
//----
//類似,提供是否是符類型
import std.traits;
// ...
static if (isSomeChar!T) {
// ... char, wchar, 或 dchar ...
} else {
// ... 不是 ...
}