diff --git a/src/example_11/.gitignore b/src/example_11/.gitignore new file mode 100644 index 0000000..94b0e62 --- /dev/null +++ b/src/example_11/.gitignore @@ -0,0 +1,15 @@ +.dub +docs.json +__dummy.html +docs/ +/example_11 +example_11.so +example_11.dylib +example_11.dll +example_11.a +example_11.lib +example_11-test-* +*.exe +*.o +*.obj +*.lst diff --git a/src/example_11/dub.json b/src/example_11/dub.json new file mode 100644 index 0000000..504806f --- /dev/null +++ b/src/example_11/dub.json @@ -0,0 +1,9 @@ +{ + "authors": [ + "alexander" + ], + "description": "Данные и функции", + "license": "proprietary", + "name": "example_11", + "targetPath": "bin" +} diff --git a/src/example_11/source/app.d b/src/example_11/source/app.d new file mode 100644 index 0000000..a6dca72 --- /dev/null +++ b/src/example_11/source/app.d @@ -0,0 +1,202 @@ +import std.stdio, std.string, std.conv, std.algorithm; + +bool find1(int[] haystack, int needle) +{ + foreach (v; haystack) + { + if (v == needle) + return true; + } + return false; +} + +int[] find2(int[] haystack, int needle) +{ + while (haystack.length > 0 && haystack[0] != needle) + { + haystack = haystack[1 .. $]; + } + return haystack; +} + +unittest +{ + int[] a = []; + assert(find2(a, 5) == []); + a = [1, 2, 3]; + assert(find2(a, 0) == []); + assert(find2(a, 1).length == 3); + assert(find2(a, 2).length == 2); + assert(a[0 .. $ - find2(a, 3).length] == [1, 2]); +} + +void bump1(ref int x) +{ + ++x; +} + +unittest +{ + int x = 1; + bump1(x); + assert(x == 2); +} + +ref int bump2(ref int x) +{ + return ++x; +} + +unittest +{ + int x = 1; + bump2(bump2(x)); // Два уве­ли­че­ния на 1 + assert(x == 3); +} + +void fun(in int x) +{ + // x = 42; // Ошиб­ка! Нель­зя из­ме­нить па­ра­метр с клю­че­вым сло­вом in +} + +int divrem(int a, int b, out int rem) +{ + assert(b != 0); + rem = a % b; + return a / b; +} + +unittest +{ + int r; + int d = divrem(5, 2, r); + assert(d == 2 && r == 1); +} + +bool verbose; +void log(lazy string message) +{ + if (verbose) + writeln(message()); +} + +unittest +{ + int result = 100; + log("foo() returned " ~ to!string(result)); // аргумент вычисляется (происходит обращение к "message") только если verbose истина +} + +/** + * Параметры типов + */ + +T[] find3(T)(T[] haystack, T needle) +{ + while (haystack.length > 0 && haystack[0] != needle) + { + haystack = haystack[1 .. $]; + } + return haystack; +} + +unittest +{ + double[] d = [1.5, 2.4]; + assert(find3(d, 1.0) == null); + assert(find3(d, 1.5) == d); + string[] s = ["one", "two"]; + assert(find3(s, "two") == ["two"]); +} + +// Вы­ра­же­ние if в сиг­на­ту­ре функции во все­ус­лы­ша­ние за­яв­ля­ет, +// что функ­ция find при­мет па­ра­метр haystack ти­па T[] и па­ра­метр needle ти­па E, +// толь­ко ес­ли вы­ра­же­ние haystack[0] != needle воз­вра­ща­ет ло­ги­че­ский тип +T[] find4(T, E)(T[] haystack, E needle) if (is(typeof(haystack[0] != needle) == bool)) +{ + while (haystack.length > 0 && haystack[0] != needle) + { + haystack = haystack[1 .. $]; + } + return haystack; +} + +unittest +{ + double[] d = [1.5, 2.4]; + assert(find4(d, 1.0) == null); + assert(find4(d, 1.5) == d); + string[] s = ["one", "two"]; + assert(find4(s, "two") == ["two"]); +} + +/** + * Перегрузка + */ + +T1[] find5(T1, T2)(T1[] longer, T2[] shorter) + if (is(typeof(longer[0 .. 1] == shorter) : bool)) +{ + while (longer.length >= shorter.length) + { + if (longer[0 .. shorter.length] == shorter) + break; + longer = longer[1 .. $]; + } + return longer; +} + +unittest +{ + double[] d1 = [6.0, 1.5, 2.25, 3]; + float[] d2 = [1.5, 2.25]; + assert(find5(d1, d2) == d1[1 .. $]); +} + +/** + * Функции высокого порядка. Функциональные литералы + */ + +T[] find(alias pred, T)(T[] input) if (is(typeof(pred(input[0])) == bool)) +{ + for (; input.length > 0; input = input[1 .. $]) + { + if (pred(input[0])) + break; + } + return input; +} + +unittest +{ + int[] a = [1, 2, 3, 4, -5, 3, -4]; + // Най­ти пер­вое от­ри­ца­тель­ное чис­ло + auto b = find!(function bool(int x) { return x < 0; })(a); + auto c = find!((x) { return x < 0; })(a); + writeln(b[0], ' ', c[0]); +} + +// По­лу­чив зна­че­ние x ти­па T, воз­вра­тить функ­цию, +// ко­то­рая на­хо­дит пер­вое зна­че­ние, рав­ное x, в мас­си­ве эле­мен­тов ти­па T + +// T[]delegate(T[]) finder(T)(T x) if (is(typeof(x == x) == bool)) +// { +// return delegate(T[] a) { return find3(a, x); }; +// } + +auto finder(T)(T x) if (is(typeof(x == x) == bool)) +{ + return (T[] a) { return find3(a, x); }; +} + +unittest +{ + auto d = finder(5); + assert(d([1, 3, 5, 7, 9]) == [5, 7, 9]); + d = finder(10); + assert(d([1, 3, 5, 7, 9]) == []); +} + +void main() +{ + +}