Вы находитесь на странице: 1из 538

D

16

The D Programming
Language

Andrei Alexandrescu

H I G H

High tech

D
H.

.

.
H.
.
.
.
.
.

.
D. - . . - .: -, 2012. 536 c., .
ISBN 978-5-93286-205-6
D - , -

.
,
(, -, ),
, ,
.
D - D,
. -
, .
, , ,
, D.
;
D;
, ,
; ,
, .
,
- ,
D, .
ISBN 978-5-93286-205-6
ISBN 978-0-321-63536-5 ()
-, 2012
Authorized translation of the English edition 2010 Pearson Education, Inc. This
translation is published and sold by permission of Pearson Education, Inc., the owner
of all rights to publish and sell the same.
,
.
, , .

-. 199034, -, 16 , 7,
. (812) 380-5007, www.symbol.ru. N 000054 25.12.98.
16.04.2012. 70x100 1
. 33,5 . .
Konica MinolLi
, . -. . 1, . 6
.: (495) 926-63-96, w w w .bukivedi.com,info@bukivedi.com. 1298.

....................

..
.
.
.
..................
1 .3 0

.13
. 14
. 18
. 21

.23

..................................... 29

1.1. .
....
....
. .
.31
1.2.
..
.34
1.3.0
.35
1.4.
.36
1.4.1.
.............
.36
1.4.2.
.
.
..
. 39
1.4.3..-
.41
1.5.0 .
.44
1.6.
.49
1.6.1. ..
................
.53
1.7.
.........
. 55
1.8.
..
...
. 57

2. . ..
2.1.
2.1.1.
2.2.
2.2.1.
.
2.2.2.
2.2.3.
...
2.2.4.3
..................
2.2.5..
2.2.6.

2.2.7.
....
2.3.
.
.........................
2.3.1. L- -.
2.3.2.
.........

. 59
.61
.61
.62
. 62
.63
.64
.66
.67
.. 72
. 73
. 75
.75
.76

2.3.3.
. 79
2.3.4.
.80
2.3.5.

.84
2.3.6.
.86
2.3.7.
.
.89
2.3.8. .
.89
2.3.9.
.90
2.3.10.

.90
2.3.11. .
.91
2.3.12. .
.92
2.3.13.
, ..94
2.3.14.
.94
2.3.15.
.94
2.3.16..
.95
2.3.17..
.95
2.3.18.
.
.96
2.4. .
.96

3.
3.1.
3.2.
3.3.
3.4.

-

i f ......................
static if

. 100

..

..

101
. 101
. 102
. 103

3.5.HHCTpyK4HHSwitch

.106

3.6.
final switch
3.7.
..
3.7.1. while ( )
3.7.2. do-while ( ).
3.7.3. for ( )
..
3.7.4. foreach ( ).
3.7.5.
3.7.6. continue .
3.8. goto ( )
..
3.9. with
3.10. return
..
3.11. .
..
3.12. m ixin .
..
...
3.13. scope

. 108
. 109
. 109
. 109
. 109
. 110
. 111
114
114
. 116
117
117
. 119
. 120

3.14.HHCTpyK4HHsynchronized.

3.15. a sm .
3.16. .

.125

..
..

4. ,
4.1. .
4.1.1. .
4.1.2. .
4.1.3.
.

. 125
. 126

. 130
. 130
.132

.132
. 134

4.1.4. .
. 135
4.1.5.
.. .
137
4.1.6.
..
. 137
4.1.7. .
..
. 137
4.1.8.
..
. 139
4.1.9.
...
140
4.1.10. .length
143
4.2. .
. 144
4.2.1.
. 146
4.2.2. .
.. ..
. 146
4.2.3.
..............
. 146
4.2.4. .
147
4.2.5.
. 148
4.2.6.
.. . .
. 148
4.2.7..
.149
4.3.
. 149
4.4. .
... .
151
4.4.1. .
..
152
4.4.2.
.153
................
..
. 154
4.4.3.
4.4.4.
...
. 154
4.4.5.
....
. 154
4.4.6. .
155
4.4.7. .
..
. 156
4.5.
. 156
4.5.1. ..
.156
4.5.2.

. 157
4.5.3.
. 160
4.5.4. + =
. 160
4.6. -
. 164
4.7.
. 166

5. .
5.1.
5.2.
5.2.1. ,
( r e f) .
..............
5.2.2. ( in)
5.2.3. ( out) ..
5.2.4. ( lazy).
5.2.5. ( static)
5.3. .
..
..
...
5.4. .
..
5.5.
...
5.5.1.
5.5.2.
...
5.6. . .

170
171
173
174
175
176
177
178
179
181
. 183
. 185
. 188
. 190

5.6.1.
.
5.7. .
5.8.
..
5.8.1. , ... , ...
, !
5.9. . .
5.9.1. @property
5.9.2. - .
..
5.10.
5.10.1.
.
5.10.2.
.
5.10.3.
. .
5.11.
..
..
5.11.1.
5.11.2. nothrow
..
5.12. .

6. . - .

. 192
. 193
. 194
. 196
. 197
. 199
. 201
.203
. 203
. 205
. 209
. 214
.214
. 217
.218
. 225

6.1.
.. . .
.225
6.2.
- . . .
. 227
6.3.
. 231
6.3.1.
.232
6.3.2.

. 233
6.3.3.
.235
6.3.4. ..
. 237
6.3.5.
..
. 237
6.3.6.
.239
6.3.7.

...............244
6.4. .
6.4.1.
.245
6.4.2. - .
.........
..
. 246
6.4.3. - .
..
. 247
6.4.4.
.248
6.4.5. .
..
. 249
6.5.
.
..............
. 251
6.6.
.
........................
. 251
6.6.1. .
.253
6.7. . .
..
..
. 254
6.7.1.private
.255
6.7.2.package
........
.255

6.7.3. protected
..
. 255
6.7.4. public . . . .
.. . .
. 256
6.7.5.export.
.256
6.7.6.?.
.257
6.8.0.
.. ..
.260
6 .8 .1 .strin g to S trin g ().
...
.260
6.8.2. size_t toHash()
..
. 261
6.8.3. bool opEquals(Object rhs).
. 261
6.8.4.intopCm p(O bjectrhs).
.265
6.8.5. static Object factory (string className)
. 266
6.9.
.268
6.9.1. (NVI)
. .269
6.9.2.
. 272
6.9.3. .
..
. 274
6.10.

274
6.11. .
. 278
6.11.1.
.280
6.11.2.
.. 281
. ..
.282
6.12.
.283
6.13.
.287
6.13.1.
. .
. 288
6.14.

6.14.1. .
.292
6.15. ..
.294
................
.296
. ..
6.17.
.299

7.

. 301

7.1.
.302
7.1.1..
.303
7.1.2.
-
7.1.3. -
. 305
7.1.4. .
. 316
7.1.5. .
..
..
. 317
7.1.6..
.321
7.1.7..
.322
7.1.8.

. 32
7.1.9. , .
.324
7.1.10. .
@disable .
. 325
7.1.11. .
. 328
7.2.

..
..
. 331
7.3.
.334
7.3.1.
. 336
7.3.2.
. 337

10

7 .4 .a lia s.
7.5.
( template)
7.5.1. .
7.5.2. 1.
7.6. m ixin template
7.6.1. mixin.
7.7..

8. .

.338
. 341
. 343
.344

. 345
. 347
.348
.349

8.1. immutable
. 350
8.1.1. . .
. ..
. 351
8.2. immutable
. 353
8.3. .
.354
8.4.
.356
8.5.
immutable.. 35
8.6. const
. 359
8.7. const immutable
. 361
8.8. .
. 362
8.9.
..
.363

9 ,

.364

9.1.
. 364
9.2. .
..
.. ..
.366
3.3. .
.369
9.4.
, (nothrow),
Throwable
. 370
9.5.
..
. 370
9.6. ,
. 373
9.7. .
. 376

10.

. 377

10.1. .
....
. 378
10.2..
.381
..
.382
10.4.
.384
..
.385
10.6. . .
. 389
10.6.1. enforce () a sse r t.
. 389
10.6.2. assert(false) -
. 391
10.7. -
. 392
10.8.
...
. 394
10.8.1. .
..
. 394
10.8.2. . . .
.396
10.8.3.
.398
10.9. . .
..
. 398

11

.401

11.1.
...
.401
ll.l.l.O e i p o rt
.403
11.1.2.
. 405
11.1.3.
.406
11.1.4.
public import.
.409
11.1.5. static import
. 410
11.1.6.
.411
11.1.7.
. 412
11.1.8. .
..
. 414
11.1.9.
..................
.415
11.2.
.
. 418
11.2.1. .
. 419
11.3.2. @ safe, @ tru sted @ sy ste m .
. 420
11.3. .
..
. 422
11.3.1.
. 423
11.3.2.

..
. 423
11.4.
.424
11.5.
+ + .
. 425
11.5.1. + + .
. 426
11.6.K nK >4eB0e^0B0deprecated

.427

11.7.

11.8.0
11.9. D .
11.10. .
......................
11.10.1. x86
11.10.2. x86-64
11.10.3.
11.10.4.
11.10.5..

.427
.429
.429
.431
. 432
. 435
. 436
.437
.441

12. .
12.1. D
. . ..
12.2. .
12.2.1.
.
12.2.2.
. .
..
1 2 .2 .3 .n ep erp y3K aon ep aT op acast.

.443
.445
. 445
.446
. 447
.448

12.2.4.

12.3.
.450
12.3.1.
..
. 451
12.3.2.
.452
12.4..
.453
12.5.
...
.454

12

12.6.
....
.456
12.7.
. 458
1 2 .8 .0 $ .
.............
.458
1 2 .9 .I I e p e r p y 3 K a f o r e a c h .

.459

12.9.1. foreach .
12.9.2. foreach .
12.10. .
12.11. - : opDispatch
12.11.1. opDispatch
12.12. .

.459
.460
. 462
.463
.465
.466

1 3 . .

.469

13.1.
. 470
13.2. .
. 473
13.3. , , ( ) . . . .
. 477
13.4.3 .
.479
13.4.1.
.480
13.5.
. 481
13.6. receive . . . .
.483
13.6.1. .
...
.485
13.6.2.
.
. 486
13.7. - . .
.486
13.8. .
.488
13.9. .
.490
13.10.
.
. 492
!. . . . .
.493
13.11.1. :
shared .
. 494
13.12.

13.12.1. . . 496
13.13.

. 497
13.14. . . .
.502
13.14.1. == .
.503
13.14.2. = =
..
. 504
13.14.3.
...
.506
13.14.4.
:
13.15. synchronized .
. 508
13.16.

..
. 510
13.16.1. ....
.511
13.16.2.
.512
13.17. .
. 515
13.18.
..
517

.
.

..

. 518
. 523

06

-
++.
++.
++:
(, 2004)
++
++, .

++: 101 (, 2005).

,
,
, .
2006 -
D , .
D
D.
.
,
-
. Facebook.

- - ,
: , ,
.
- ,
. ,
,
.
, , . ,
, , - .
- 1.
, ,
,
.
,
2 - , ,
, .
- .
.
- , .
, , .
, .
.
Empire: W argam e of the Century3.
, ,
.
, , , ,

1 Quentin R. Wald The Wright Brothers as Engineers: an Appraisal and Flying


with the Wright Brothers, one Mans Experience, 1999.
2

Bertrand R. Brinley Rocket Manual for Amateurs*, Ballantine, 1968.

,
,
Civilisation. . http://www.classicempire.com/. - . .

15

. ,
. ,
, .
++, ,
(!).
.
.
,
, , , .
- , . 1999
. M ars.
D - ,
. D.
D
, ,
D2. ,
, D
,
.
( )
,
. , D

: , -,
.
, :
. , D - . ,
, .
, .
, D - ?
,
IDE1 - ,

. D ,
,
, D
,
. .
, IDE.
, - -
()
.
1 IDE (Integrated Development Environment) -
.- . .

16

.
, - .
, - . .
,
,
.
, , , - .
, , .
: , , , .
, , , .
,
.
, .


. ,
. D
, ,
. ,
, , ,
(hijack)1, ,
, -
.
, !
, ,
, ,
, ,
, . D -
. ? , , D
,
. ,
D .
,
,
. , D
. ,
D D.
1 : -
(, . .) ,
(- )
,
- , , . D
. . http:// dlang.org/hijack.
html. - . ..

17

. ?
,
? ,

. ,
.

.
D -
. ,
. - ,
. D

.
,
(.
++).
D 2006 . -
,

. D2 ,
D.
D , - .
,
. , ,
.
, D
.
D, ,
.
,
D, .
. , !

2010 .

, ++ .
,
. ++
Java C #.
,
.
.
- . ,
( , ++)
. ,
.
Java C #
++.

++ ,
. ++
. Java C#
,
++.
- ,
, ++. ,

,
, .
- - .
,
-
, - Java C #
++.
++ -
.
(
),
( )
.

19

, ,
Java C # ++.
-
, .
D - ++
. Java C #, D ++,
. -
, - 1.
- , - .
, D .
++
. ++ ,
(C++11), ,
. D
. ++, C++Ox
(
),
, (
). D
,
.
, ++ , , D
, .
++ ,
, , ,
. D
, . ++
, ,
, ,
. D, , ,
, ,
.
, D co- ++, -
.
( ) , , , D
:
. D,

1 , .
, D ,
.

20

,
, , ,
?
( ) D

. , - ,
. D,
, D
. , , ,
, , D .
, , ,
. - ,
.
. ,
, * (
, )
: , ,
.
: . . ,
, :
--main, :

1.
-. ,

,
- " .
2 ,
.
,
, - .
3:
bool find(int[] haystack, int needle);
.
, , .

2010 .
1 - ,
( ) - , ,
.
. - . .
2

, 3- , -, 2008.

, : bool (1^[ ] ,
int );. - . .

D ,
. , .
, , -
.
, *.

, ,
, , . ,
,
, (
, dmd
d-program m ing-language.org). ,
.
, ,
,
, .
, ,
,
, .
, ,
, . ,
,
case switch.
.
.
- character.

. .
1
(symbol). , double, main
1 .
. - .: , 1975.

22

++ . 1
(, ) .
- . *
symbol*, (,
). character .
,
, (sign) (+ -).
, , ,
. , char ,
, ,
, . , D char
( )
UTF-8 (, ,
, unsigned char ).
D - byte (
) ubyte ( ).
char, wchar dchar, i n t ,
.
- statem ent.
, if, switch, while, . D
,
(operator overloading) +, *, %
, .
statem ent* .
.
. D, ,
,
. ,
- , . , D
, ,
.
.
, - ,
.
. - .

1 . JI., . . : 2- . - . .M.: , 1990.

, .
-
,
,
. -
.
D - ,
,
,
,
. , D
- , ,
.
, , , D . ,
, ,
,
D.

.
D , :

. D -
. , ,
. D
, D -
.

. D , , .
,
, .

. - ,
- .
.

. D

24

, ,
,
.

. D ,

. D
( ,
) ,
.

. ,
,
, ++, Java
. D
.

. D ,
.

, .

. ,
>>1. D
.
, ,
,
.
, -
- . , D
,
.


, . ,
,
. , . ,
(, ++, Java C #),
-
, (
) . (
, D -. , .)
, , ,
, ,
1 . - . .

25


.
,
, , .
,
,
, ,
,
, - . ,
,
, , , - ,
.


1 - .
,
.
2 3 -
.
, , D
. , ,
.
, .
4 : ,
.
. D - ,
. -
UTF.

.
,
.
-. 5
:
( ) ,
.
* , D
, .
6 -
. ,
. 7
, struct, ,
, .

26

,
. 8 .
,
, . 9
. 10
D,
.
( 9) ,
-
. 10 , .
11
,
D. 12 ,
,
. , 13 D
.


, D - . - 1990-
, ++, ,
, , ,
, .
; ,
: (backend), ,
.
. -

,
.
, .
++,
D,
*. ,
, D1. ,
D1 ,
. 2 0 0 6 D1 ,

, Java ++. , D1
, , ,
,
. :
D1 ,
-
, .

27

D1 -
, D1 .
D2,
D.
. , ,
. ,
-
, D1.
, ,

. ,
, .
, D ,
, ,
,
( ).
D ++,
,

() , .
:
; D
.
, , -
. , , - .

D ,
. d i g i t a l mars.D U senet. ,
,
. , digitalmars.D
.
dmd1
, (Sean Kelly) (Don
Clugston). ,
( ).
, ,
. ,
, ,
1 D dmd Digital Mars D.
Digital Mars - ,
. - . .

28

, , , , . -
.
D .
, D
.
, -
.
dmd. , ,
D
. ( ) ,
. ,
. , .
,
,
. ,
( , ,
).
(Alejandro Arag6n),
(B ill B axter), (K evin Bealer), (Travis Boucher), (M ike Casinghino), (Alvaro Castro C astilla), (Richard Chang), , (Stephan D illy), (Karim Filali),
(M ichel Fortin), (David . Held),
(M ichiel H elvensteijn), (Bernard
Helyer), (Jason House), (Sam Hu),
(Thomas Hume), (Graham St. Jack), (Ro
b ert Jacques), (C hristian Kamm), (Daniel Keep), (Mark Kegel), , (
K hesin), (Sim en Kjaeras), (Cody Koeninger), (D enis Koroskin), JIapcy (Lars
K yllingstad), (Igor Lesik), (Eugene Letuchy), (Pelle Mansson), (Miura Masahiro), (Tim M atthews), , , (Fawzi Mohamed), (Ellery New
comer), (Eric Niebler), (Mike Parker),
(Derek Parnell), (Jeremie Pelletier),
( R ipolles), (Brad Roberts),
(M ichael Rynn), (Foy Savas),
(C hristof Schardt), (Steve Schveighoffer),
(Benjam in Shropshire), (David Simcha),
(Tomasz Stachowiak), (Robert
Stew art), (K nut Erik Teigen),
(C ristian V lasceanu) (Leor Zolman).

2 2010 .

, , :
import s t d. s t d i o ;
void main() {
w r i t e l n ( "Hello, worl d!' );

}
, ,
, , , - , D
, (top-level)
. (
, ;
, D ,
main, .)
, void main - i nt main,
( 0)
.
. Hello,
worldU (, !) -
. ,
. IDE,
, -
.
, , hello.d,
:
$ dmd h e l l o . d
$ ./h ello
H e llo , world!
$

30

1. D

$ (
:\\\> W indow s ///%
U N IX , OSX, L inux, Cygwin).
-,
. W indows, ,
rdmd.exe (
D) . U N IX -
shebang1. D
:
#!/usr/bin/ rdmd

hello.d
. ,
:
$ chmod u+x h e l l o . d
$ ./h ello.d
H e l l o , w orld !
$

(chmod ).
: rdmd
,
.
, .


, ,
.
hello.d
import s t d . s t d i o ;
std.stdio
.
import #include,
++,
import Python:
-
.
import , .
D
, .
, , .
Shebang ( shell bang: shell - , bang - ),
shabang (# - sharp) -
!///. - . .

31

1.1.

main.
, , , void.
main writeln ( ,
std.stdio),
. ln ,
writeln .
- .
.
-
, .
- .

1.1.
- ?
,
.
/*

*/
import st d . s t di o ;

void main() {
/ / ,
immutable inchesPerFoot = 12;
immutable cmPerInch = 2.54;
/ /
foreach (feet; 5
7) {
foreach (inches; 0
inchesPerFoot) {
wr i t el n ( f e e t , ..... inches, - - \ t "
( f e et * inchesPerFoot + inches) * cmPerInch;

}
}
>

:
5' 0
5 11
5 2

'

'

6 110 '
6 1 1 11

152.4
154.94
157.48
208.28
210.82

foreach (feet; 5. .7) {...} - ,


feet,
5 6 ( 7 , ).

32

1. D

Java, ++ C #, D /* */
/ / (, ,
, ).
- . -,
:
immutable inchesPerFoot = 12;
immutable cmPerInch = 2.54;
, ,
immutable. ,
: ,
. 12
, inchesPerFoot
( D int);
2.54 cmPerInch
( double).
f e et inches: ,
, - .
,
:
immutable int inchesPerFoot = 12;
immutable double cmPerInch = 2.54;
foreach (int feet; 5

7) {

}
.
,
. ,
, .
: byte, short, int
long, 8, 16, 32 64 .
,
: ubyte, ushort, uint ulong. (
unsigned, ). : f loat (32- IEEE 754), double (64-
IEEE 754) r eal ( ,
, ,
64 ; , Intel real -
79-
IEEE 754).
. , 42,
, ,
,
.
immutable byte inchesPerFoot = 12;

1.1.

33

byte, 12
8 , 32. ,
( -),
in t, - double.
D, ,
.
, - D: +, -, *, / %
, ==, !=, <, >, <=, >= ,
fun(argument1, argument2) ..

writeln. :
writeln 5 ( , ,
D). writeln
-,
(writeln), (printf) ++ (cout). ( writeln D)
(
). D
(
), ( ),
( ++). :
writeln
.
.
writefln, :
writefln("%s' %s' ' \t%s", fee t , inches,
(feet * inchesPerFoot + inches) * cmPerInch) ;

- ,
writefln .
% (
pr in tf ): %d - , %f -
%s .
p r i n t f ,
, :
int double - ,
%s,
? . D
wri tefln
.
: 1) %s

2)
, ,
, p r i n t f
( , p r i n t f
).

34

1. D

1.2.
D, , ,
, - (
Hello, world! writ eln ;).
.
D -
. ,
, { }, ,
foreach.
. ,
, ,
:
foreach ( f e et ; 5
7)
foreach (inches; 0
inchesPerFoot)
wr i tef l n( "%s' %s' '\ t %s" fee t , inches,
( f e e t * inchesPerFoot + inches) * cmPerInch);


( ), -
(
, , ).
,
. , ,
, . :
, (
,
,
),
. ,
, .
P ython
- (
).
, , -
, , Python, . D
,
(. e.
). ,
,
(
P ython) - ,
.
, if:
i f ('<) >,> e l s e <>

1.3.

35

,
[10], ,
, if- - for foreach.
, ( D)
, , ,
.

1.3.
main
, D.
, -
: , ,
,
, . ,
pow, double in t,
double, :
double pow(double base, int exponent) {
}
(base exponent )
(storage class),
1.
pow .
ref,
,
, . :
import std.stdio;
void fun(ref uint x, double ) {
x = 42;
= 3.14;
}
void main() {
uint = 1;
double b = 2;
fun<a, b);
writeln(a, '' " b);
}
42 2, x ref uint,
x,
. ,
1 ,
, - , .

36

1. D

b, -
fun.
* ,
, - i n o u t . , in -
, . out
ref, ,

. ( T
, T . i n i t .
.)
.
, ,
(
), (-),

. .

1.4.
( -
, ) ,
,
.
, .
, D .

1.4.1.
,
:
, , ,

. :

,
- . ,
( ),
. -
,
.
, , , (
- ,
0, 1, 2, ...).
, D.

1.4.

37

import s t d . st d i o , s t d . s t r i n g ;
void main() 1
slze_t [ s t r i n g ] dictionary;
foreach ( line; st di n . by L i ne Q) {
/ /
/ /
foreach (word; s p l i t t e r ( s t r i p ( l i n e ) )) {
if (word in di c ti ona ry ) continue; / /
auto newID = d ic ti o na ry . l e n g th ;
dictionary[word.idup] = newID;
writeln(newID, ' \ t ' word);

}
}
}
D (-),
V, V[K].
, dict ionary s i z e _ t [s t ri n g]
- , . ! in d i c t i on ar y n cT H H, word
dictionary. , : dictionary[word.
idup] = newID1.
,
s t r i n g - , .
T T[ ]
:
int[] = new int[20]; / / 20 ,
int[] b = [ 1, 2, 3 ]; / / , 1, 2, 3
, D .
arr arr.length.
arr.length , .
,
.
(
arr.ptr)
. , ,
, ,
. ,
. , ,
.

.idup - , (immutable)
. ,
, .
. . .

38

1. D


foreach:
i n t [ ] a r r = new i nt[ 20] ;
foreach (elem; a r r ) {
/* . . . elem.

}
elem
arr. elem arr.
, ref:
/ / ar r
foreach ( re f elem; a r r ) {
elem = 0;

}
, , foreach ,
.
, foreach :
l n t [ ] months = new int [ 1 2] ;
foreach ( i, ref e; months) {
e = i + 1;

}
1 12.
(. ),
foreach :
foreach ( i ; 0
months.length) {
months[i] = i + 1;

>
D , ,
, in t[5].
,
, .
:
;
.
,
.dup:
i n t [ ] = new int[100];
i n t [ ] b = ;
/ / ++x 1 x
++b[10];
/ / b[10] 1, a[10]
b = a.dup; / / b
++b[10];
/ / b[10] 2, a[10] 1

39

1.4.

1.4.2. .
.

- ,
, .
,
:
, ,
, .
D ,
, ,
. , ,
, ,
,
, <.
, .
binarySearch:
import std. ar r ay;
bool binarySearch(T)(T[] input, T value) {
while (!input.empty) {
auto i = input . le ng t h / 2;
auto mid = i np u t[ i ] ;
i f (mid > value) input = input[0 . i] ;
el se i f (mid < value) input = i n p ut [ i + 1
el se return true;

$];

}
return false;

}
unittest {
assert(binarySearch([ 1, 3, 6, 7, 9, 15 ], 6));
asser t( !bi nar ySear ch( [ 1, 3, 6, 7, 9, 15 ], 5));

>
(T) binarySearch
. T
.
. binarySearch
T . T
(, ), :
a s se r t ( bi na r yS ea r ch !( i n t ) ( [ 1, 3, 6, 7, 9, 15 ], 6));


.
,
!(.. .), -

40

1. D

(...).
, ,
, .
Java, C # ++, ,
, , D
, < >
, . .
- ++ (
,
- ,
1). ,
< > 2.
,
, .
.
Java C # : <
>.
. D
, .
, ,
! (
) (
, , ).
-
auto ,
: i mid
, .

binarySearch .
, unittest (
unittest, , ,
). main
, -u n ittest. unittest
,
: ,
. ,

, , unittest binarySearch;
D
.

-
, , object.template fun<arg>(),
.

, - .

41

1.4.

1^ .. b] input
b, b. == b, ,
> b, .
;
. $

, ; , input[0 .. $] -
, input.
: ,
binarySearch,
.

, .
, , ,
.
binarySearch,
input:
import st d. ar r ay;
bool binarySearch(T)(T[] input, T value) {
i f ( i n p u t . empty) return f al se;
auto i = i nput. length / 2;
auto mid = i np ut [ i] ;
i f (mid > value) return binarySearch(input[0
i f (mid < value) return binarySearch(i nput[ i + 1
return true;

i ] , value);
$]], value);

}

. ,
,
,
. :
( ),
.

1.4.3. . -
,
.
, ?
, .
,
uint, ,
,
.
, :

42

1. D

import std. al gori t hm, s t d . s t d i o , s t d . s t r i n g ;


void main() {
/ /
u i n t [ s t r i n g ] freqs;
foreach ( l i ne ; st di n. byLi n e ( ) ) {
foreach (word; s p l i t t e ( s t r i p ( l i n e ))) {
++freqs[word.idup];

>
}
/ /
foreach (key, value; f re qs) {
writefln(''%6u\t%s", value, key);

}
}
, ham let.txt1 (
h ttp ://erd a n i.c o m /td p l/h a m let.tx t)
,
:
1
1
1
1
1
2
1
1
1
1

outface
come?
b lank et,
operant
reckon
liest
Unhand
dear,
parley.
share.

, , , : ,
, .
-
.

, sort
-nr ( num erically - reversed ), .
,
:
/ /
s t r i n g [ ] words = freqs.keys;
s o r t ! ( ( a , b) { return f r eq s[ a] > freqs[b] ; })(words);
foreach (word; words) {

1 . - . .

1.4.

writefln(''%6u\t%s"

43

freqs[word], word);

}
. keys
freqs ,
. , .

sort!((a, b) { return freqs[a] > freqs[b]; })(words);
:
sort '.(' >)(< >);
, !(...), -
, -
,
:
(, b) { return freqs[a] > freqs[b]; }
- - ,
,
. -
, D ,
,
:
. ,
- , ,
,
.
-, ,
. -
freqs, main, , , .
, ,
-.

, D (, ,
).
:
929
680
625
608
523
453
444
382
3 61

the
and
f
to
I

my
in
y ou

44

1. D
358

H an\.

:
. 1.
. -
*Hamlet (),
. 358 - ,
. - 116 ,
. 58 -
.

1.5.
,
. , - :

() .
.
, :
s t r u c t PersonaOata {
u in t totalWordsSpoken;
u i n t [ s t r i n g ] wordCount;

}
D (struct) (class) .
,
: - ,
,
.
,
- -
/ / ! !. ,
, -
. , ++ ,
,
.
.
,
, s t r uc t -
. ,
(
PersonaData):
PersonaData[string] info;

H a m (.) - . - . .

1.5.

45

, , - info
hamlet.txt. :
, ,
. ,
, hamlet.txt,
(
):
P o l . Marry, I w i l l t e a c h y o u ! T h i n k y o u r s e l f b a b y
_That y o u h a v e t a ' e n t h e s e t e n d e r s f o r t r u e p a y ,
Which a r e n o t s t e r l i n g . T e n d e r y o u r s e l f more d e a r l y ,
Or ( n o t t o c r a c k t h e w i n d o f t h e p o o r p h r a s e ,
^-Running i t t h u s ) y o u ' l l t e n d e r me a f o o l .
Oph. My l o r d , h e h a t h i m p o r t u n ' d me w i t h l o v e
I n h o n o u r a b l e f a s h i o n .
P o l . Ay, f a s h i o n y o u may c a l l i t . Go t o , g o t o !

,
goto. :
,
, , , ,
- .
,
.
,
( std.regex),
,
.
a.startsWith(b), std.algorithm, ,
b.
main
, ( ,
),
- :
i mp or ts t d. a lgo r i th m, std.conv, st d. ct ype, std. regex,
std.range, s t d . s t d i o , s t d . s t r i n g ;
s t r u c t PersonaData {
uint totalWordsSpoken;
u i n t [ s t r i n g ] wordCount;

}
void main() {
/ /
PersonaData[string] info;
/ / info
s t r i ng currentParagraph;
foreach (line; s t d i n . byLine()) {
i f ( l i n e . s t a r t s Wi t h ( " ")

46

1. D
&& l i n e . l e n g t h > 4
&& i s a l p h a ( l i n e [ 4 ])) {
/ /
currentParagraph ^= li ne [ 3 .. $];
} else i f ( l i n e . s t a r t s W i t h ( " ")
&& l i n e . l e n g t h > 2
&& i s a l p h a ( l i n e [ 2 ] ) ) {
/ /
addParagraph(currentParagraph, info);
currentParagraph = t o ! s t r i n g ( l i n e [ 2

$]);

}
}
/ / ,
pr i n t Re s u lt s (i n f o) ;

}
, , ,
t o ! s t ri n g( li n e[ 2 .. $]). ,
?
foreach,
, line.

, byLine ,
line. l i n e char[], .
, , ,
, ( t o!s tri ng(l ine[2 . . $]), )
. ,
- ,
, . ,
currentParagraph,
,
; t o!string,
. st ri ng , to
.
to! st ri ng , , -
. ,
, ,
( ,
to ).
, : line current
Paragraph .
l i ne char[], ,
; currentParagraph
s tr in g ,
. ( : THnastring - immutable(char)[],
.

1.5.

47

4.)
, l i ne
currentParagraph .

,
t o!s tri ng. .
, ,

-
, .
s t r i n g
. .
, s t r i n g ,
.
- . ,
,
, char[], .
PersonData , ,
.
, , (, )
( private), -,
, , .

( , N aN 1 null
,
. addParagraph,
.
, 1,:' . be, or not to bethat i s the question. " ,
, "
find. haystack.find(needle)
haystack,
needle. ( needle haystack , find
.) ,
. -,
,
.
tolower. ,
, - - ,
, , him. him .
, s p l i t
.
1 NaN (Not Number, ) -
. ,
.

48

1. D

, : regex( "[ \ t , .;:?]+ ").


, s p lit ,
[ ], .
, ,
:
void addParagraph(string li ne , ref PersonaData[string] info) {
/ /
line = st ri p ( l i n e );
auto sentence = s t d . a l g o r i t h m . f i n d ( l i n e , " ");
i f (sentence.empty) {
return;

}
auto persona = l i n e [ 0 .. $ - sentence. length];
sentence = t o l o w e r( st r ip ( se n te n c e[ 2
$]));
/ /
auto words = s p l i t ( s e n t e n c e , regex("[ \ t , ; :?]+"));
/ / I ns e r t or update information
i f (!(persona in i nf o ) ) {
/ /
info[persona] = PersonaData();

>
info[persona].totalWordsSpoken += words.length;
foreach (word; words) ++info[persona].wordCount[word];

>
addParagraph .
,
PersonaData,
. uint - ,

,
.
,
, printResults:
void pri n t Re sul t s( Per sona Da t a[ st r i ng ] info) {
foreach (persona, data; inf o) {
writefln("%20s %6u %6u" persona, data.totalWordsSpoken,
data.wordCount.length);

>
}
-? !
Queen
Ros
For
Fort
Gentlemen
Other

11 04
738
55
74
4
105

500
338
45
61
3
75

1.6.

49

Guil
176
349
Mar
231
423
Capt
92
66
70
Lord
49
Bot h
44
24
Oph
998
401
Ghost
683
350
A ll
17
20
Player
14
16
1507
Lae r
606
2626
P ol
870
92
Priest
66
Hor 2 129
763
Ki ng 4153 1251
C o r ., Volt
11
11
Bo t h [Mar
8
8
Osr
379
179
110
Mess
79
S ailor
42
36
Servant
11
10
34
Ambassador
41
Fran
47
64
Clown
298
665
77
Gent
101
Ham 11901 282 2
Ber
220
135
150
112
Volt
37
Rey
80

. ,
,
. (Volt):
,
.
(Sailor), .
(Queen) (Oph):
10% , ,
25%.
(, "Both [Mar "),

, .
- (
) .

1.6.
- ;
, ,
. -

50

1. D

,
. , -:
,
. ! ,

,
. -
awk,
. -
- , .
, (
s t a t s ) ? :
, ,
s t a t s ,
(
- ),
. :
$ echo 3 1.3

4 10 4 . 5

1 5 I s t a t s Min Max A v e r a g e

1
10

4.225
$ _


.

. .
:
, .
,
.
-
.
- .
,
,
. ,
, .

. ,
, ; /
[39] .
, (
) . -
,
. , Min

1.6.

51

, ,
. - - .
Average
(
). ,
.
,
-

.
i n t e r fa ce Stat {
void accumulate(double x);
void postprocess();
double r e s u l t ( ) ;

}
.
, , ,
, .
, ,
Min,
Stat.
cl ass Min : Stat {
pr ivat e double min = double.max;
void accumulate(double x) {
i f (x < min) {
min = x;

}
}
void postprocess() {} / /
double r e s u l t ( ) {
return min;

>
}
Min - , , D
. c las s Min: S ta t Min
, Stat. Min
, Stat,
(
Min ). Min
(, private) min (
)
accumulate. Min - (
double),
.
,
s t a t s ,

52

1. D

,
, ( Min,
Min),
Stat.
import s t d . c o n t r a c t s , s t d . s t d i o ;
void ma i n ( st r ing[ ] args) {
Stat[] stats;
foreach (arg; args[1
$]) {
auto newStat = c a s t ( S t a t ) O b j e c t . f a c t o r y ( " s t a t s . " ' arg);
enforce(newStat, "Inval id s t a t i s t i c s function: " ^ arg);
s t a t s ^= newStat;

}
for (double x; s t d i n. readf(" %s " &x) == 1; ) {
foreach (s; s t a t s ) {
s . accumulate(x);

}
}
foreach (s; s t a t s ) {
s . p o s t p r o c e s s ( );
w riteln(s.result());

}
}
.
main , :
.
D ,

. sta ts
args. , D ( ) , :
args[1 .. $].
auto newStat = c a s t ( S t a t ) O b j e c t . f a c t o r y ( ' s t a t s . " ^ arg);
, , ,
. - , ^ ,
.
- Min, - 'stats.M in ",
O bject.factory. Object - ,
D. fac
tory, ,
( ),
, ,
.
, Object, factory null.
, Min - ,
Object. factory.
, -

1.6.

53

. , ,
.
( D Java)


.
stats.Min, Min? D
,
, .
,
.
, s t a t s . d , D ,
, , s t a t s .
.
Min Min. ,
, , 0bject.factory("4To "),
,

Object. ,
, , ,
Object.factory, State.
(type castin g). D cast(T) expr
. ,
, ,
.
, , ,
, .
, .
( readf)
accumulate , .
readf ,
.
%s ", ,
. ( ,
x double.) ,
, - .

1.6.1. .
, Min;
accumulate,
1.
, , ,
1 . -
double.max . - . ..

54

1. D

. -
, ,
,
. ,
Min (, ,
). , ,
,
.

.
c l a s s IncrementalStat : St at {
protected double _ re s ul t ;
a b s t r a c t void accumulate(double x);
void postprocess() {}
double r e s u l t ( ) {
return _r esult ;

>
}
:
, ,
.
, .
IncrementalStat ,
Stat, accumulate
. Min:
c l a s s Min : I ncrementalStat {
this() {
_ r e s u l t = double.max;

}
void accumulate(double x) {
i f (x < _ r e s u l t ) {
_ r es u l t = x;

}
>
}
, Min
t h i s () ,
. ,
,
,
(, ,
, , ).
,
:
c l a s s Average : I ncrementalStat {
p r i v at e u i n t items = 0;

1.7.

55

this() {
_r esul t = 0;

}
void accumulate(double x) {
_ res ul t += x;
++items;

}
override void postprocess() {
i f (items) {
_ r es ul t /= items;

}
}
}
, Average , items,
items = 0 ( ,
, , ,
,
). , : Average
, _result . ,
, ,
.
, _result N aN
, , -
,
. , Average
postprocess, IncrementalStat . D
( ) ,
override,
(
- ,
- ).
fin a l, -
(
).

1.7.
:
import s t d . s t d i o ;
s t r u c t MyStruct {
i nt data;

>
cl as s MyClass {
i n t data;

56

1. D

void main() {
/ / MyStruct
MyStruct s1;
MyStruct s2 = s1;
++s2.data;
w r i t e l n ( s 1 . d at a ) ; / / 0
/ / MyClass
MyClass c1 = new MyClass;
MyClass c2 = c1;
++c2.data;
w ri t e l n ( c 1 .d a t a ) ; / / 1

>
, MyStruct
MyObject. ,
,
(, ++ - ,
). ,
c1 c2
, s1 s2, , .
MyStruct ,
',
,
,
. ,
, ,
.
MyClass ,
: ( new
MyClass),
,
.
, ,

. ,
,
. ,
, , (
), , (
, ).
;
.
, ,
. ,
++ . ,
,
, .

1.8.

57

,
, ,
,
,
, . -
, , .
- .
, , ,
. ,
, -, ,
.
D .
. -
. 6 7
,
. ,
(
s t a t s ) ,
.
- ,
.
(, ,
++, - slicin g,

. D slicin g .)
, ,
. ,
. ,
, , -
, , -
.
, .
,
; , ,
.

1.8.
- , -
.
,
.
, - . -,
,
.

58

1. D

,
. -
, ,
. ,
D , ,
, .
, .
,
.

2
.

- , ++, Java C #,
D
. -
. ,
,
. ;
,
. , ,
.
:
, .
,
, .
D ,

. ,
,

D ,
, , ,
.
:

: void, ,
,
.

null: typeof(null) - null,


, , ,
.

60

2. .

() : bool true
fa lse.
: byte, short, in t long,
ubyte, ushort, uint ulong.
: flo a t, double real.
: char, wchar dchar,
, .

. 2.1 D
. D
, ,
.
<ran>.init; int . in it - .
2.1. D

void

n/a

typeof(null)

null

n/a

bool

()

false

byte

, 8

ubyte

, 8

short

, 16

ushort

, 16

in t

, 32

uint

, 32

long

, 64

ulong

, 64

flo a t

32 ,

float.nan

double

64 ,

double.nan

real

, real.nan

char

, 8 , UTF-8

0xFF

wchar

, 16 , UTF-16

0xFFFF

dchar

, 32 , UTF-32

0x0000FFFF

61

2.1.

2.1.
, -
, ,
, .
: ,
,
D. ,
, ,
.
D - :
-
( Z z), 1,
C992 [33, D].
, abc, oc5, _, _1, _AbC, Ab9C _9x ,
9abc _abc - .
( ),
,
. -
, .

2.1.1.
. 2.2 - ,
.
.
2.2. D
abstract

el se

macro

switch

alias

enum

mixin

synchronized

align

export

module

asm

extern

template
new

this

auto

f al s e

nothrow

throw

final

null

body

finally

as se r t

t r ue
try

bool

f l oat

out

typeid

break

for

override

typeof

1 , . . . .
2 C99 - ,
. - . .

62

2. .

byte
case
cast
catch
char
class
const
continue
dchar
debug
default
delegate
deprecated
do
double

foreach
function
goto
ifIf
immutable
import
in
inout
int
interface
invariant
isIs
long
lazy

package
pragma
private
protected
public
pure

ubyte
uint
ulong
union
unittest
ushort

real
ref
return

version
void

scope
short
static
struct
super

wchar
while
with


. , th is
, super ,
-
(. 6). $

. null
, .
typeid(T) T (

).

2.2.
2.2.1.
() - true () fa lse ().

2.2.

63

2.2.2.
D , 1,
.
, , L, U, , LU, Lu, UL ul.
:

: in t, in t, long;

U/u: uint, uint, ulong.


L: - long.

U/u L : - ulong.

:
auto

d
e
f

=
=
=
=
=
=

42,
42u,
42UL,
4000000000,
4000000000u,
5000000000u;

//
//
//
//
//
//

in t
b u int
ulong
long; in t
uint; uint
ulong; u in t

(
, ).

:
auto ta rg e tS ala ry = 15_000_000;
, 0x
0X, 0-9, a-f, A-F _.
0b 0B,
0, 1 .
, .
, ,
.
2.1, 1024 ,
. :
1) , , 2)
*
2. ( )
, .

1 ,
- ,
. std.conv.octal!777
0777 . - . . .
2 , : . 2.1 2.2 -
().

64

2. .

. 2.1. .
( ,
), .
( ) , ,
s U\u\L\UL\uL\Lu\LU

2.2.3.

.

:
, 1
, ()
. 2 - , e, E, e+,
E+, e- E-, 3.
f, F L. ,
- e/E f/F ,
1
( :
), ,
( -
) . - . .
2

10 - - exponent,
e. - . .

10
. .

p - . -

65

2.2.

, . f/F
f lo a t,
L - real. double.
,
- . , ,
, .
,
,
,
, 10 - 2. ,
, ,
.
; ,
D IEEE 754,
(
IEEE 754).

0x 0X, ,
.
1, p, P, p+, P+, p- P-
( !) .
- -
; -
.
2 ( 10,
). f, F
L2. :
auto

d
e

=
=
=
=
=

1.0,
/ / double
.345E2f, / / b = 34.5
f lo a t
10f,
/ / f l o a t -
10.
/ / d double
0 x 1 . f f f f f f f f f f f f f p 1 0 2 3 , / /
/ / double
f = 0XFp1F; / / f = 30.0, f lo a t

2.2
D. ,
, :

1 - - power, 2
. - . .
2 , , D C99,
,
.

66

2. .

. ,
,
. , 0x.p1 0xp1 - ,
, 0e1, .e1 0x0.0 .

. 2.2.

2.2.4.
- ,
, . ,
: '\ '.
D, , escape1 (. . 2.3).
D
: '\u03C9' ( \u, 4 ), '\U0000211C' (
\U, 8 ) \&copy;'
(, \& ;). -
, 52, -
. ,
, .

1 - ( . escap e- ), /
- ,

( ). - . .

67

2.2.

2.3. D
-

char

( )

\\

char

\a

char

(Bell, ASCII 7)

\b

char

Backspace (ASCII 8)

\f

char

(ASCII 12)

\n

char

(ASCII 10)

\r

char

(ASCII 13)

\t

char

(ASCII 9)

\v

char

(ASCII 11)

\<7-3 >

char

UTF-8
( 3778)

\x<2 > char

UTF-8

\u<4 > wchar

UTF-16

\U<5 >

dchar

UTF-32

\&< >;

dchar

2.2.5.
, , ,
. D

. , , D
, (
. 2.3), W YSIW YG 1 ( ,
-).
WYSIWYG ,
;
- W indow s.

1 WYSIWIG - What You See Is What You Get* ( ,


) - ,
, -
(, . .). - . .

68

2. .

, (quoted strings), - ," '.


- . 2.3 .
, ,
:
auto c r l f = " \ r \n " ;
auto = " \" \"
, " "\n";

:
(
, \n),
.

2.2.5.1. : WYSIWYG, ,
,
W YSIW YG- r" '' (' "),
1 ( ). W YSIW YG (
), , .
, , ,
W YSIW YG. ,
,
. :
auto = ' \ ............. .";
,
' " (.......), " - (...... ). .
, - . D
- .
auto =

q"[KaKaR-TO

""

' ' [

]];

, ,
, , q' [ ]".
,
. : q
, -.
- ,
, : , w
1 . - . ..

69

2.2.

d. : [ ], ( ), < >, { }.
,
, .
,
:
auto =

q"/flp0CT0

/''; / / " "


:
auto = q''///"; / / .
auto b = q ''[]]" ;
/ / .
auto = q " [ [ ] ] " ;
/ / ,
/ / . . [ ] .

-
,
:
auto = q"EndOfString

EndOfString";

, D ,
. q{
}. , { },
D
.
auto = q{ foo(q{hello});
auto b = q{ >;
auto = q{ _EOF__ };

};
//
" foo(q{hello});
/ / ! "' -
/ / ! __ EOF__ - ,

D
, ,
( ) x' ".
;

, - -
. .
auto
= x"OA"
/ / To , "\xOA''
b = x"00 F BCD 32"; / / To , "\x00\xFB\xCD\x32''

,
D ,
: !
auto x = import( "resource.bin'');

70

2. .

x
resource.bin. (
#include,
, .)

. dmd -J
.
, import,
UTF-8. -
.

2.2.5.2.
? :
import s t d . s t d i o ;
void m ain() {
writeln(typeid(typeof(''Hello, world!")));
}
typeof , typeid
. :
i m m u t a b l e ( c h a r ) []

, -
. , string,
, - ( ), immutable(char)[].
: , -
.


.
,
.
, ,
. immutable ,
,
,
:
auto = " ";
a [ 0 ] = 'X '; / / ! !

immutable - (
8); ,
. immutable(char)[] str, str
, str :

2.2.

71

immutable(char)[] s t r = "One";
s tr [ 0 ] = "X"; / / !
/ / immutable(char)!
s t r = "Two"; / / , s t r

, ,
immutable :
immutable char[] = "One";
a[0] = "X'; / / !
= "Two"; / / !

, : immutable
,
(. 13).
, ,
.

, (13 '"Hello, world! ")


.
; ,
'"Hello, world!" [13],
13 . ,
. D
. ,
,
, :
immutable(char)[13] = "Hello, world!";
char[13] b = "Hello, world!";

T[N]
T[ ] .
,
:
import s t d .s td i o ;
void main() {
immutable(char)[3] = "'Hi! ";
immutable(char)[] b = ;
w rite ln (a .le n g th , "
b .len g th ); / / "3 3"

-
, ,
, - char, wchar dchar1.

1 w d - . wide () double () - . .
.

72

2. .

: string, wstring
dstrin g - immutable(char)[], immutable(wchar)[]
immutable(dchar)[] .
4- dchar,
dstring ; , 2-
wchar, wstring,
strin g . ,
, , :
w string x = ", !";
/ / UTF-16
d s tr in g = ", !"; / / UTF-32

,
: , w d,
s trin g , wstring dstring .

2.2.6.
- .
, int
double?
, 1:
auto somePrimes = [ 2u, 3, 5, 7, 11, 13 ];
auto someDoubles = [ 1.5, 3, 4.5 ];

. ,
, :
auto co nstants = [ 2.71, 3.14, 6.023e22 ];
co n s tan ts[0 ] = 2.21953167; / / " "
auto s a l u t a t i o n s = [ "" "" "" ];
s a l u t a t i o n s [ 2 ] = " ";

:
s a lu ta tio n s , ,
. ,
strin g .

,
?: (. 2.3.16). l i t ,
, true ? lit[0 ] ; lit[1]

1 , ,
[1, 2,] - 2,
. :

"_", ,
. - . ..

2.2.

73

L. i -
l i t [ i ] l i t
true ? L.init : l i t [ i ] L.
L .
, , , -

1: ,
. , [1, 2, 2.2] double,
[1, 2, ] uint, ?: int
uint uint.
:
auto famousNamedConstants =
[ "" : 3.14, "e" : 2.71, " " : 2.22 ];
:
.
, ,
. .
V
V[K]. , famousNamedConstants
double[string].

2.2.7.
;
.
(
-) , .
,
, ,
/ .
D
in situ 2 - .
-
, .

5. :
auto f = function double(int x) { return x / 10.; };
auto = f(5);
assert(a == 0.5);

1 1989
,
. . . .
2 In situ (.) - . - . .

74

2. .


, , ,
function, .
- ,
f.
f - , int
double. double function(int) (
: function
), f :
double function(lnt) f = function double(int x) { return x / 10.; };
function double
,
. : function
,
.


, .
auto f = function(int x) { return x / 10.; };

x, ,
,
.
, ,
? function
delegate:
int = 2;
auto f = delegate double(int x) { return * x / 10.; };
auto = f(5);
assert(a == 1);
= 3;
auto b = f(5);
assert(b == 1.5);
f delegate double(int x).
function delegate.
: delegate ,
function- ( delegate ,
),
?
delegate? : . ,
delegate
,
. , function

2.3.

75

, delegate - ( ,
- ).

2.3.
D
. ,

.
: 1- -
.
.

2.3.1. L- -
, 1-
. , ,
: 5 = 10 .
, l-.
1- (
r-).
. ,
= b
, 1-; b,
, - -1.
1- :

, , ,
( immut
able);
;

( );

,
ref ( );

1- -. -
, : ,
( enum;
. 7.3) , x + 5.
: 1- ,
- ,
(. 6)
(. 8).
1 . left-value right-value. - . ..

76

2. .

2.3.2.
;
.
:
1.
D, (
: D ).
2. .
3.
.
4. ( )
.
1 ,
. D
++,
D. D

,
2 0 0 0 , ,
,
. 2 D
, ++. D

,
.
2.3
. ;
.

,
- , .

2.3.2.1.
,
42, int.
:
ubyte x = 42;
42
int. int x,
.
( int
ubyte). ,
.

2.3.

77

. 2.3. .
,
.
,
.
,
(. 2.3.2.1)
D ,
,
(value range propagation):

.
.

,
. ,
, 42, , 42,
.
,
,
,
. ,
int :

78

2. .

void fun(int val) {


ubyte ls B y te = v a l & OxFF;
ubyte hsByte = v a l > 24;
}
,
val. ,
, ,
val ,
.
, fun,
val & 0xFF [0; 255] val, val > 24
. , a oop x eoae o eccubyte( ap ep,val & 0x1FF
val > 23), .

; , ulnt,
1 0 0000, ushort. ,
,
, . :
void fun(int val) {
ubyte x = (val & 0xF0F0) / 300;
>
&
0 0xF0F0 ( 6 1 6 8 0 ).
0 205.
ubyte.


. ,
, ,
. :
void fun(int x) <
i f ( x >= 0 && x < 42) {
ubyte = x; / / !
/ / i n t ubyte!

}
}
, ,
. ,
.

2.3.

79


. ,
,
- .
cast
(. 2.3.6.7).

2.3.3.
,
.
.
, , ,
.
,
. ! ( . 2 .3.6.6),
bool.
:

- ,
-
.
ulong,
ulong
ulong.
long,
long
long.

uint,
uint
uint.


int int.

(.
. 2.3). . :
ushort x = 60_000;
assert(x / 10 == 6000);
10 in t
x int .
. 2.3 , pa30BaHHeushort ^ ^ ( ) 5 1 ^> short ^>
int. , 6 0 0 0 0
short -5536, int
a sse r t .
.

80

2. .

2.3.4.
- .
(. 2.1), true
fa lse (. 2.2.1), (. 2.2.2),
(. 2.2.3), (.
2.2.4), (. 2.2.5),
(. 2 .2.6) (. 2.2.7);
, null.
: assert, mixin, is
.

2.3.4.1. assert
, assert,
. : 1)
(
), 2) (
true) 3) , (
-null).
^) .
, . assert
AssertError. ^,
) (
string) ,
AssertError ( , ).
assert void.

D (-release
dmd), assert
( ).
, assert ,
,
.
assert ,
.
11.
, a ssert(fa lse), assert(0) ,
assert
, . (
)
HLT,
.

.

2.3.

81


(. 2.3.15), -

() || a s s e rt(fa ls e ).
10
, a s s e rt.

2.3.4.2. mixin
, mixin
,
, ,
.
.
, mixin
. 1(),
, .

,
. , D - ,
.
, D
, ,
,
.

-
,
DSEL1. DSEL,
D,
, ,
D mixin
D. DSEL
SQL-,
(- yacc). , p rin tf,
DSEL. ,
p rintf, - ,
.
D DSEL
( , ,
..); , b i t f i e l d s
( std.bitmanip)

1 Domain-specific embedded language (DSEL) - -


. - . .

82

2. .

D ,
.

2.3.4.3. is
i s ( Wid
get? Widget Gadget?)
,
D. is
. ,
is.
1. is(Tnn) is(Tnn ),
. , ,
. :
bool

=
=
=
=

is(in t[]),
is (in t[5 ]),
is(in t[-3 ]),
is(B lah );

//
//
//
//

True,
True,
F alse,
F alse

i n t [ ] -
i n t [ 5 ] -

( Blah )


, ; ,
is ([[ ]x []] ) ,
fa ls e . ,
, .
,
is.
s t a t i c i f
. s t a t i c i f 3,
: s t a t i c i f

, .
s t a t i c i f ( i s ( W id g e t[ 100] [ 100] ManyWidgets)) {
ManyWidgets lotsO fW idgets;

>
2. is(Twn1 == 2) is(Tnn1 == 2)
True, 1 2 . (
alia s.)
alias ulnt UInt;
a s s e r t ( i s ( u i n t == U In t) );

,
1 is.

83

2.3.

3. is(Tnn1 : 2) is(Tnn1 : 2)
True, 1
2. :
bool
= is(in t[5 ] : in t[]),

//
//
b = i s ( i n t [ 5 ] == i n t [ ] ) , / /
= i s ( u i n t : lo n g ),
//
d = i s ( u lo n g : long );
//

t r u e , i n t [ 5 ]
i n t [ ]
FALSE;
tru e
tru e

, ,
1 is.
4. is(Tnn == ) is(Tnn == ) ,
.
: s tru c t, union, class, in te rfa c e , enum, function, delegate,
super, const, immutable, inout, shared return. i s ,
.
, (. 2.4).
2.4.
is(Tnn == )

______ ...
struct

union

class

in te rfa c e

enum

(. 7)

fun ctio n

d e leg a te

d e le g a te

super

(. 6)

co nst

immutable

in out

shared

retu rn

, , d e le g a te

84

2. .

2.3.4.4.

: , (<>)
, <>.

2.3.5.
2.3.5.1.
. b
b, .
- ,
. b
new (. 6).

2.3.5.2.

( ++ - - )
,
++:
( 1-),
. (
2.3.6.3.)

2.3.5.3.
fun()
fun. fun(< , >)
fun .
fun.

. @property,

. fun - , ,
(. 2.2.7)
, delegate.
5.

2.3.5.4.
arr[i] i -
(
0). , i
. i ,
arr.
(, arr[i] = e)

2.3.

85

arr - , ,
. i ,
arr, RangeError. i .

. ( ;
. 4.1.2)
.

2.3.5.5.
arr - () , arr[i .. j]
, arr i- j-ro
( ). i j,
, .
arr[] arr.
-,
arr. :
int[] = new int[5]; / /
int[] b = a[3
5]; / / b
b[0] = 1;
b[1] = 3;

assert(a == [ 0, 0, 0, 1, 3 ] ) ; / /
1 > j j > a.length, RangeError.
1 == j, . a rr
a r r [ i .. . ,
arr + i f l o a r r + j ( + j). i > j , r e RangeError,
. (
, . 4.1.2)
.

2.3.5.6.
a.new T, - cla ss,
T, . - ?
, ,
new .
new ( 2.3.6.1),
,
6 ( 6.11).
, .

86

2. .

2.3.6.
2.3.6.1. new
new:
new
new
new
new

(<')[1

<>

( < ) ' (<_>0.)


( <> )
<>[ <_ >]
( ') >

(<>).
new T new T(<_>)
.
. ( new T new T()
, .)
,
6,
(. 6.3), 7, (.
7.1.3). (
new), . 6.11.3.
.
new T[n] ,
n T ,
T.init T[].
:
a u to a r r = new i n t [ 4 ] ;
a s s e r t ( a r r . l e n g t h == 4);
a s s e r t ( a r r == [ 0, 0, 0, 0 ] ) ; / /

, :
a u to a r r = new i n t [ ] ( 4 ) ;

new T(4), T
in t[]. ,
arr in t[].
,
. ,
.
. , ,
, :
a u to m a trix = new i n t [ ] [ ] ( 4 , 8);
a s s e r t ( m a t r i x . l e n g t h == 4);
a s s e r t ( m a t r i x [ 0 ] . l e n g t h == 8);

2.3.

87

auto matrix = new int[][](4);


foreach (ref row; matrix) {
row = new int[](8);
}

. ,
, .

c o r e . g c ,

. -
, , ,
.
,
new, , .
new(aApec) T :
.
.
, ,
m a l l o c
D.

2.3.6.2.
,
.
& ( 1-
) T*, .
*p ,
; *& .
7,
D
.

2.3.6.3.
( )
++ --
( )
, .

2.3.6.4.
^a ( )
, .
.

88

2. .

2.3.6.5.
+ :
.
- 0 - ;
-.
:
, ( ,
2.3.3), -55u - 4_294_967_241,
uint.max - 55 + 1.
, , -
. D, ,
-
, .
-,
- , - " + 1;
,
1 .
, .

2.3.6.6.
! bool false,
( 2.3.4.1),
true.

2.3.6.7.

, . ,
, , ,
,
.
,
,
, . n oB T aK :cast(T n n) .


.
-
c la s s interface.
.

-
.

2.3.

89

-
;
.

-
.

/ -
, , .


, ,
.

2.3.7.
: ^^ (
) . ,
. pow(ocHoeaHne,
), D
( s t d . m a t h ) .

.
- ,
- .

2.3.8.
( * b),
( / b) ( %b).
.
/ b %b b
, .
(,
7 / 3 2, -7 / 3 -1). % b
, == ( / b) * b + % b, 7 % 3 1,
-7 %3 -1.
D
. .
%b b ,
( ) ,
:

, () < a b s ( b ) ;

q, r == - q * b.

, %b
NaN.

90

2. .

2.3.9.
+ b, - b
^ b.
.
2.3.3.
b,
.

T, , .
,
b.

2.3.10.
D ,
: b, b > b.
b ;
(,
, b >= 0;
), b (
) b , b b .
- , .
> b .
, .
,
:
i n t = -1;
i n t b = 1;
a s s e r t ( b == - 2 ) ;
i n t = 1;
a s s e r t ( c == - 1 ) ;
i n t d = > 1;
a s s e r t ( d == +2147483647);

/ / OxFFFF_FFFF
/ / OxFFFF_FFFE
/ / OxFFFF_FFFF
/ / 0x7FFF_FFFF

, ,
, b - , .
b ,
:
i n t = 50;
u i n t b = 35;
<< 33;
au to =
au to d = >>

/ /
b;/ /
b;/ /


2.3.3.

2.3.

91


2 ( 1) 2 ( 1) 2.
, .
: * k / k; k ,

, ,
. .

2.3.11. in
- ,
V[K], i n V* (
V). (, ),
.
- n u l l .
, , ,
!( in ), !i n
, i n .
, i n b
? :
. ,
, ,
. - :
double[string] table;
if ("hello'' in table) {
++table["hello"];
} else {
table[hello"] = 0;
}
,
, .
, , :
double[string] table;
auto p = "hello" in table;
i f (P) <
+ + .p ;

} else {
table["hello"] = 1;
>

92

2. .

2.3.12.
2.3.12.1.
== b, boo l,
. -, ,
.
:

: -0
+0, N aN N aN 1;
;

c l a s s
opE qu als (. 6.8.3);

s t r u c t
;
(. 12).

!= b .
i s b (alias equa
lity): b ,
t r u e :

b - , tr u e ,
b - ;

b == b.

,
:
import s t d . s t d i o ;
void main() {
auto = "- '";
auto b = ; / / b
i s b && w riteln("A ra, . ');
auto = "- () ;
i s | | writeln("eceo.
.");

}
1 IEEE 754
: -0 +0. ,
, .
, . , ,
-0.0 D,
,
.

2.3.

93

, b
, .
,
( == b ),
, i s b f a l s e . ,
i s b , == b (
).
!( i s b) ! i s b.

2.3.12.2.
D < b,
<= b, > b >= b (, , ,
).
. ,
-0 0, -0 < 0 f a l s e .
N aN ,
f a l s e ( ).
NaN
. ,
NaN,
(floating-point exception).
:
,
. D
s t d . c . f e n v .

2.3.12.3.
D -
. <= b <
.
- ,
boo l.
:
<= b <
, .

( <= b) < , <= b .
, 3 <= 4 < 2 !
.
, <= b <
: <= b && b < ,
b . P yth on Perl 6

94

2. .

,
, < b == > d < e. D -
. ,
( Python Perl 6, ,
), ,
, D -
.

2.3.13. .
| b, ^ b & b
, .
(
),
.
, b .
2.3.3.

2.3.14.
, && b
b.

b vo id ,
. , b,
, , t r u e ,
f a l s e .

b vo id , void.
, b. b .

&& void
if :
strin g lin e;
l i n e == "#\n" && w r i t e l n ( ' ' y c n e u m o

");

2.3.15.
11 b b.

b vo id , bool.
, t r u e . b,
, , tr u e .

b vo id , void.
, b . b .

2.3.

95

s tr in g line;
lin e .le n g th > 0 | | lin e = "\n";

2.3.16.
- if-th en -else
? b : , , , .
, b;
.
b ,
. ( T)
( ):
1. b , .
2. b - , 32
in t, T ;
.
3. - ,
, T .
4. , T .
5. ( ),
T ( 6).
6. b b ;
- , T ,
.
7. .
, b 1-,
1-, :
i n t x = 5, = 5;
bool which = tru e;
(which ? x : ) += 5;
a s s e r t( x == 10);

2.3.17.
= b co= b,
^^, *, /, %, +, -, ^, , , >, |, ^ &,

.
.

96

2. .

>= = b,
:
(, b , :[1 * 5 + j] *= s q r t( x )) .
to= ,
=, , (
), , (
). co=
( =) , /= b = -= d -
, /= (b = ( -= d)).

2.3.18.
, ,
. -
. :
i n t = 5;
i n t = 10;
i n t = ( = b, b = 7, 8);

, b
10, 7 8 .

2.4.
D
. . 2.5. D.
.
2.5. D

>

(. 2.1)

,<>

,
( ) (. 2.1)

th is

(. 2.1.1)

super


- (.
2.1.1)

( $

) (. 2.1.1)

null

, (. 2.1.1)

97

2.4.

typeid(T)

TypeInfo, T (.
2.1.1)

true

(. 2.2.1)

false

(. 2.2.1)

<>

(. 2.2.2 2.2.3)

<>

(. 2.2.4)

<>

(. 2.2.5)

<>

(. 2.2.6)

<>

(. 2.2.7)

assert(a)

,
, ;
(release) (. 2.3.4.1)

assert(a, b)

, b (.
2.3.4.1)

nixin(a)

mixin (. 2.3.4.2)

<IsExpr>

i s (. 2.3.4.3)

( )_____________ (. 2.3.4.4)
a.b

(. 2.3.5.1)

++


(. 2.3.5.2)


(. 2.3.5.2)

a(<aPU>>

(<aprnu> =
, ) (. 2.3.5.3)

[<apr>]

(<apr> = ,
) (. 2.3.5.4)

a[]

(. 2.3.5.5)

a[b .. ]

(. 2.3.5.5)

.< new>

(. 2.3.5.6)

&a

(. 2.3.6.2)

++


(. 2.3.6.3)


(. 2.3.6.3)

98

2. .

2.5 ()

*a

(. 2.3.6.2)

(. 2.3.6.5)

+a

(. 2.3.6.5)

!a

(. 2.3.6.6)

^a

(. 2.3.6.4)

(T).a

cast(T)

< new>

(. 2.3.6.1)

^" b

(. 2.3.7)

* b

(. 2.3.8)

/ b

(. 2.3.8)

% b_____________ (. 2.3.8)
+ b

(. 2.3.9)

- b

(. 2.3.9)

^ b

(. 2.3.9)

(. 2.3.10)

(. 2.3.10)

> b

(
) (. 2.3.10)

in b


(. 2.3.11)

== b

;
; , == b ==
(. 2.3.12.1)

!= b

(. 2.3.12.1)

is b

(true, b
) (. 2.3.12.1)

!is b

, !( i s b)

< b

(. 2.3.12.2)

<= b

(. 2.3.12.2)

> b

(. 2.3.12.2)

>= b

(. 2.3.12.2)

| b

(. 2.3.13)

^b

(. 2.3.13)

&b

(. 2.3.13)

&& b

(b v o id ) (. 2.3.14)

II b____________ (b void ) (. 2.3.15)


? b :

;
, b, (. 2.3.16)

= b

;
; *= b += - .
*= (b += ) (. 2.3.17)

+= b

;
= b,
, : 1) (
1-), 2) b 3) , = 1 b, ( - 1-,

-=b

= b

/= b

%=b

&=b

|= b

^= b

^= b

( b )

= b

= b

>= b

, b

;
,
(. 2.3.18)


D. D
- if , w h ile , f o r .
D
.
,
D
.
- ,
, , s t a t i c i f (. 3.4).
, ; ,
- , s t a t i c i f
. s w itc h (. 3.5)
, ,
, .

f i n a l s w itc h (. . 3.6),

. fo re ac h (.
3.7.4 3.7.5) ;
f o r ,
. m ixin (. 3.12) . scope (. 3.13)

, t r y /
c a t c h / f i n a l l y , .

3.1. -

101

3.1. -
(. 1.2),
, :
= b + ;
transmogrify(a + b);

.
, ,
, :
1 + 1 == 2; / /

3.2.
- (, )
, .
. (
): , ,
.
, ,
,
:
uint widgetCount;

void main() {
writeln(widgetCount); / /
auto widgetCount = getWidgetCount();
writeln(widgetCount); / /

}
writeln
widgetCount,
widgetCount.
,
, ,
( 2.2.1), writeln(.widgetCount).
,
, :
void main() {
auto widgetCount = getWidgetCount();
/ /

{
auto widgetCount = getWidgetCount(); / / !

>
}

102

3.

,
:
void main() {

<
auto i = 0;

>
{
auto i = "eye"; / /

)
double i = 3.14;

/ /

>
.
,
,
; ,
,
. ,

( D
) (
- ),
, - .

3.3. if
D if,
, :
i f ( <>) <, *

i f ( <>) <> e l s e <7>

,
if. , D
,
.
:
i f ( == b);
w r ite ln (" a b ");

, ,
, ,

103

3.4. static if

, .
if ,
:
if ( == b)
, ,
.
else
if,
:
i f ( == b)
if (b == )
writeln("Bce ");

else
w rite ln (''a b. ?");

writeln , == != .
else () if. ,
, else if,
if :
if

( == b ) {
( b == )
writeln(''Bce ");
} else
w rite ln (''a b. ?");
if

if - e ls e
:
auto o p t =
i f ( o p t ==

getO p tion ();


"help")

} else i f (opt == "quiet") {


} else i f (opt == "verbose") {

} else {
s t d e r r .w r i t e f l n ( " H e n 3 B e c T H a f l o n u M H

'%s"'

op t);

3.4. static if
,
(, ),
.

104

3.

( ) -

, s t a t i c i f 1. 2:
enum s iz e _ t
g_maxDataSize = 100_000_000,
g_maxMemory = 1_000_000_000;
double transmogrify(double x) {
s t a t i c i f (g_maxMemory / 4 > g_maxDataSize) {
a l i a s double Numeric;
} else {
a l i a s f l o a t Numeric;

}
Numeric[] ;
/ /
return y[0];

}
s t a t i c i f
# i f . s t a t i c if,
. ,
; ,
e l s e ( ). s t a t i c i f
(
) ( f l o a t ,
) (
double).
s t a t i c if.
, s t a t i c if , - ,
.
,
,
, i s
(. 2 .3.4.3) (
- ).
5.


t r a n s m o g r i f y
, : Numeric { }. ,

1 -, , static*.
2

enum . ,
enum, ,
,
. - . . .

105

3.4. static if

, (, ,
),
. ,
s ta tic if. s ta tic if
,
. ,
, s ta tic if ,
( ,
;
,
). (
), :
import s td . s td i o ;
void main() {
static i f (real.sizeof > double.sizeof) {{
auto maximorum = real.max;
^' - %s!"

maximorum);

}}
.. /* maximorum - /


, - s ta tic if.
, , s ta tic i f -
, 0declaration ).
s ta tic if , , s ta tic
if , ,
,
. , Numeric ,
transmogrify:
enum size_ t
g_maxDataSize = 100_000_000,
g_maxMemory = 1_000_000_000;

/ / Numeric
static i f (g_maxMemory / 4 > g_maxDataSize) {
alias double Numeric;

} else {
alias float Numeric;
}
double transmogrify(double x) {
Numeric[] ;
.. / /
return y[0];

106

3.

if - else
y s t a t i c if s ta tic e lse .
e lse . else
i f , sta tic i f
if:
i f ()
s t a t i c i f (b) w rite ln (" a ");
e ls e w rite ln (" b ");

3.5. switch
switch
:
import s t d . s t d i o ;
void c l a s s i f y ( c h a r ) {
write("Bu ");
switch () {
case 'tt' :
writeln("3Ha< .");
break;
case ' 0 ' :
case ' 9 ' :
w riteln ("u n 0 p y .");
break;
case - :
case ' Z' : case a ' :
case ' z ' :
writeln("ASCII-3HaK.");
break;
case
,
';
'!
' ?' ;
writeln(''3HaK .");
break;
d e f a u lt;
writeln("eceM !");
break;

}
}
switch :
switch ('>) <>

> , ;
<> (, labels),
:
1. case <s>:
, <> == <a<.
(. 2.3.18),
.

107

3.5. switch

2. case <>,
<>,
...
1
2 '

<n >:

<sk* . <s>\ case <2>\,


case <>:.

3. case <:>: .. case <2>:


, <> >= <ef> - <= <2>.
4. default:
, .
<> .
case -
, <
>,
. - ,
, D
, ,
.
case default
.
, break,
switch. ++, D
break
return , .
switch (s) {
case ' a ' : w r ite ln (" a " ) ; / / ""
case ' b' : w rite ln (" b "); / / ! !
d e fa u lt: break;

>
, 'a'
'b',
goto:
switch (s) {
case ' a ' : w rite ln (" a " ) ; goto case; / / ""
/ /
case ' b' : w rite ln (" b "); / / ' a '
de fa u lt: break;

}
break return,
.
break switch,
-
.
, , :
.
:

108

3.
switch (s) {
case ' a '
case ' z ' :
break;
/ / 'w'
case ' w' :
break; / / ! Case- !
d e f a u lt: break;

}
default .
, . ,
-
.
, default; break;, ,
. ,
switch-.

3.6. final switch


switch
.
,
;
.
,
;

,
. :

, ,
switch.
fin a l switch,
case :
enum DeviceStatus { ready, busy, f a i l }
void process(DeviceStatus s t a t u s ) {
f i n a l switch ( s t a t u s ) {
case DeviceStatus.ready;
case DeviceStatus.busy:
case D e v ic e S ta tu s.fa il:

)
>
,
:
enum DeviceStatus { ready, busy, f a i l , i n i t i a l i z i n g / - */ }

109

3.7.

process
:
Error:

final

s w i t c h s t a t e m e n t mus t h a n d l e a l l

values

(: final switch )

fin al switch , enum


. <s^: .. case <2>:, default: .

3.7.
3.7.1. while ( )
, :
while ( <> ) <>

<>. , <> : <> ..


,
while.

3.7.2. do-while ( )
, ,
:
do <> while ( <>)\


. , do <>.
,
->.

3.7.3. for ( )
:
for ( ' > <^>\ <2>) '>

< >, <,> <2>( )


. <:>, ,
. < > -
(HanpnMep,auto i = 0; flo a t w ;), p a e ec o o ca o
(, i = 10;).
:
< >, <ewp,>; ,
<>, <>,
<,>.

110

3.

3.7.4. foreach ( )
,
- f o r e a c h 1,
. :
foreach (<>; <,><7>) <>
<:> <2> . , <> ( ) <^
( ) <2>.
. ,
<2> ? , ^> >= <2>?
, ,
.
() (
) (lowering).
.

<
auto _n = <2>\
auto <> = true ? <> : <7<\
for (; <> < __ n; ++<> ) <
}
_n ,
2 (
, ).
( ? , <
> fo re a ch ,
.)
, <,>, <2>
, >>
(. 2.3.16) - ?:,
.
, ?:,
, ,
,
.
, _n -
, foreach
,
1 foreach_reverse, fore
ach, .
2

, ,
2.1. - . .

111

3.7.

(<) (
12). , <,
,
< != .
,
,
++,
. .'
,
<> .
, , ,
, /
:
import std.math, s t d . s t d i o ;
void main() {
foreach (float elem; 1.0

100.0) {

w riteln(log(elem )); / /

}
foreach (double elem; 1.0

100.0) {
w rite ln (lo g (e le m )); / /

>
foreach (elem; 1.0

100.0) {
w r i te l n ( lo g ( elem)); / /

}
}

3.7.5.
foreach,
:
foreach ( <>\ '>) <>
<> ( ),
.
12, .
'> ,
. ( .)
<>
<>.

1 (STL) ++
!= , () - ,
. D , ,
, <,
, .

112

3.

,
<>.
foreach ,
; , ,
.


<> <>
.
, , <
> , ref ref <>. :
void s c a l e ( f l o a t [ ] array, f l o a t s) {
foreach ( r e f e; array) {
e *= s; / / " "

>
}
ref
e ( ), ref flo a t e.
: ref !
f l o a t [ ] a r r = [ 1.0, 2.5, 4.0 ];
foreach ( r e f f l o a t Glem; a r r ) {
elem *= 2; / /

}
foreach ( r e f double elem; a r r ) { / / !
elem /= 2;

}
:
, ref
. flo a t
double, float
double ,
- .

?
.

:
foreach (/ ,

<2>\ <>) <>

:
void p r i n t ( i n t [ ] ar r ay) {
foreach ( i , e; ar r ay) {
wri tef l n( "arr ay[ %s ] = %s;"

}
}

i, e);

113

3.7.

,
. 1 5, 2, 8]) :
a rr a y [0 ] = 5 ;
array [1 ] = 2 ;
a r r a y [ 2 ] = 8;


:
void print(double[string] map) {
foreach (i, e; map) {
writefln("array['%s'] = %s;
}
}

i, e);

print(["JlyHa": 1.283, "":499.307, "": 133814298.759])

[ ' 1] = 1 . 3 3 8 1 4 e + 0 8 ;
[''] = 499.307;
[''] = 1.283;

: ,
. ,
,
, . ,
,

.
.
-,
<t> <2> . ,
<:> (
ref).

-
:

.
.

. ,
,
. ,
;
,
, ,
. ,
.

114

3.

(
; )
.
,

. ,
: 1) , , 2) ,
.

3.7.6. continue break


continue
, while, do-while, for
foreach. , continue
.
break ,
while, do-while, for, foreach, switch
fin a l switch, .
,
, .
continue break
,
goto, .
void f u n ( s t r i n g [ ] s t r i n g s ) {
loop: foreach (s; s t r i n g s )
switch (s) {
d e f a u lt: . . . ; break;
case " l s " :
.; break;
case 'rm": . . . ; break;
case "#": break loop;

{
/ /
/ /
/ /

switch
switch
switch

/ /
/ / ( foreach)

}
}
}

3.8. goto ( )

goto. , D
:
goto <>\

<> ,
goto. ,
. :

115

3.8. goto ( )
i n t ;
mylabel: = 1;
i f ( == 0) goto mylabel;

.
, goto
, . :
void main() {
goto ta rg e t;
i n t x = 10;
ta r g e t: {} / / ! goto x!

}
, goto
(. 3.11). , goto
, . goto
: ,
if, ,
.
D , goto.
switch
goto case <;

case

->.

goto case;

case.
goto d efault;

default.
,
goto, ,
switch:
enum Pref { superFast, veryFast, f a s t, a c c u r a te ,re g u la r , slow, slower };
Pref preference;
double coarseness = 1;
switch (preference) {
case P r e f . f a s t : . . . ; break;
case P ref.veryFast: coarseness = 1.5; goto case P r e f . f a s t ;
case P ref.sup erF ast: coarseness = 3; goto case P r e f . f a s t ;
c a s e P r e f .a c c u r a t e : . . . ; break;
case P re f.re g u la r : goto d efault;
d e fa u lt:

116

3.

break continue (. 3.7.6),


(. 3.11) scope (
, . 3.13)
goto .

3.9. with
with
.
:
with ( <' ) <>
<<,

'>. 1,
struct:
import std.math, s t d . s t d i o ;
s t r u c t Point {
double x, ;
double norm() { return s q r t( x * x + * ); }

>
void main() {
Point p;
in t z;
with (p) {
x = 3;
//
- = 4;
//
w riteln(norm ()); / /
z = 1;
//

p.x
, p
p.norm, 5
z

}
}
,
with: p 1-
.
,
with,
, -
.
Point :
void f un() {
Point p;
s t r i n g = " ().";
with (p)
w rite ln (x , ":" ); / / !

117

3.10. return
/ / p.y !

}
}
,
. , w ith
, , .
, w r i te l n ( x , ":" );
w r ite ln (x , ":", p.y);,
p .
with
( ).
, w ith,
..
,
, :
with ('flwp,0 with (2)

.. with (<-) <>

w ith
, w ith
, w ith.
: D
.

3.10. return
,
return >-;

<>
,
( ) , .
v o id , <>
,
void.
, v o id ,
r e t u r n .
, , ,
.

3.11.
D
, (exceptions).

118

3.

throw,
try. , :
throw new SomeException("npoM30umo ");

SomeException Throwable.
D
, , , ,

.
,
, try,
:
t r y <
catch ('ff,> ' H^) <>
catch (<> '2>) <7>
catch ( <' '>) <>
f i n a l l y <,>

fin a lly , catch


( catch). :
try fin a lly
catch. <> - , , ,
Throwable. <> - .
. <>.
( <>
, '%>),
co <>, <2>, ..., <> < >.
<>, <> . -
<%> <> <>. ,
<> ,
catch,
. <>
, <>
.
fin a lly , t>
: ,
,
catch .
(, ,
, ).
<f> ,
. D
9.

3.12. mixin

119

goto (. 3.8)
<>, <>, ..., <> f>,
, goto .

3.12. mixin
2 (. 2 .3.4.2) ,
mixin ,
, D,
. mixin ,
mixin ,
.
,
. , ,
, ,
.
:
,
.
[60]
[34]:
u in t b i ts S e t( u i n t value) {
u in t r e su lt;
for (; value; + +result) {
value &= value - 1;

}
return re su lt;

}
u n ittest {
a s s e r t( b its S e t ( 1 0 ) == 2);
a s s e r t ( b i t s S e t ( 0 ) == 0);
a s s e r t( b its S e t(2 5 5 ) == 8);

}
, ,
, .
bitsSet
; -
( D - ).
, ;
mixin. ,
,
, mixin
. :
import std.conv;
s tr in g makeHammingWeightsTable(string , u in t = 255) {

120

3.
s t r i n g r e s u lt = "immutable u b y te [" 'to !strin g (m a x + 1 ) ^ '] "^name^" = [ ";
foreach (b; 0 .. max + 1) {
r e s u lt ^= t o ! s t r i n g ( b i t s S e t ( b ) ) ' " ";

}
return r e s u lt ^ ] ; ;

}
makeHammingWeightsTable 'immutable
ubyte[256] t = [ 0, 1, 1, 2........ 7, 7, 8, ];" 11(.
8) ,
. to!string
1.6. (
uint, bitsSet).
, ,
:
mixin(makeHammingWeightsTable("hwTable''));
u n ittest {
assert(hwTable[10] == 2);
assert(hwTable[0] == 0);
assert(hwTable[255] == 8);

}
,
: -

.
(
)
( import, . 2.2.5.1) ,
mixin,
- . :
mixin ( impo r t ( ''widget. d"));

import widget.d
, mixin .
, ,
.

3.13. scope
scope - D,
. scope
D , ,
.
scope , ,
,
.

3.13. scope

121

:
scop e(exit) <>

<> ,
().
, fin a lly try,
scope .
scope(exit) , , ,
. , g_verbose
(), .
:
bool g_verbose;
void s ile n tF u n c tio n () {
auto oldVerbose = g_verbose;
sco pe(ex it) g_verbose = oldVerbose;
g_verbose = fa lse ;

}
silentFunction ,
,
, ,
, g_verbose
.
scope(exit),
,
, scope(exit),
, try.
,
, - .
, scope(exit):
{
,'
scope(exit) <2>
<3"

}
scope - , <
> scope ( <> < > ). ,
:
{
,'
try {
<3>
} fin ally {

122

3.
' 2

>
>
. <2>
<3> ,
scope. (
,
.) , ,
scope(exit), , ,
scope(exit) scope(exit) scope(exit) ^1("?"). , ,
scope(exit):
{
<.
sc o p e(ex it) <>
3
sc o p e(ex it) <
<>

}
,
scope.
, :

<
>}

try {
<3'

try {
' ^>

} finally {
<4<

>
} finally {
<

>
}

scope(exit) .
, ,
<> <}>.
, scope(exit) LIFO1: ,
.
scope ,
try/fin ally;
1 LIFO - Last In - First Out* ( - ). . .

3.13. scope

123

: scope ,
.
try/
fin a lly - .

scope - .
. ( ,
-
scope,
.)
scope(exit)
scope(exit)
, -
try.
,
, i f for.
- C+4( D; . 7),
.
, (
CleanerUpper1?),
try. , , try - ,
scope(exit) - .
scope(success) <> <>

( ).
scope(success).
<
,
scope(success) <2>
>

}

{
<t >
bool __succeeded = true;
try {
<3>
} catch(Exception e) {
_succeeded = fa lse ;
throw e;
} fin ally {

1 CleanerUpper - ( . clean up - , ). - .
.

124

3.

i f ( _succeeded) <2>
}
>
, <> <%> ; ,
scope.
scope -
scope(failure) <>. -
>
.
scope(failure)
scope(success), ,
__succeeded fa lse , true.
{
<, >
scope(failure) <2>
<3>
}

<
', >
bool __succeeded = true;
try {
%>
} catch(Exception e) {
_succeeded = false;
throw e;

} finally {
i f (!__succeeded) <7>
}
}
<7> <3>.
scope .
, -
,
. :
import s t d . c o n t r a c t s , s t d . s t d i o ;
void tr a n s a c t io n a l C r e a t e ( s tr in g filename) {
s t r i n g tempFilename = filename ^ ".fragment";
scope(success) {
s t d . f i l e . rename(tempFilename, filename);

>
auto f = File(tempFilename, 'w");
/ / f

125

3.14. synchronized

scope(success) .
scope
; ,
,
. ,
.
,
transaction alC reate
.
transactionalCreate : ,
-, ,
.

3.14. synchronized
synchronized :
synchronized ( <: >, >2>.

) ->


. synchronized
13.

3.15. asm
D
,
. , ,
D
Intel x86. ,
D, x 8 6 .
, ,
D , .
,
, ,
, , , W indow s,
L inux,
(
). D ,
, .

. , :
asm < >

:
asm { < }

126

3.

, asm,
: D.
D 11; ,
x 8 6 . D
[12].

3.16.
D ,
, 111 if ,f i n a l sw itchnscope.Ta6 3.1 - D (
).
3.1. (<> - ,
<> , <o> , <x> - )

>;

<e>.
,
, (. 3.1)

{/ ... <2>)

<]< <2>
,
(,
return) (. 3.2)

asm <>

(
> ,
D).
*86

(. 3.15)

break;

(
) switch, for, foreach,
while do-while ,
(. 3.7.6)

break <x>\

switch,
for, foreach, while do-while,
'X>:, ,
(. 3.7.6).

continue;

(
) for, foreach, while
do-while
(. 3.7.6)

continue <x>;

for, foreach,
while do-while, 'X>\,

(. 3.7.6)

127

3.16.

do <> while (<s>);

<>
, <s> (. 3.7.2)

for (.,- 'fl/; <?>) <7>

',>,
-,
, <s^
, <2>,
<}>(. 3.7.3)

foreach (>x>; <s^ .. <0 >

<>,
<x> <s^
1, <x> < 2>.
, <s/ >= <7>. <>,
<> (.
3.7.4)

foreach (ref
4 0 <x>;' <>)' <>

<>, <x>
<s>
. <s>

- (. 12).
ref, <x>

(. 3.7.5)

foreach (<x>,
4 1 ref or>u <x>;
? <s>) <> ,
<x,>. <> -
, <x,>
, <x.> -
. -1>

,
( 0) (. 3.7.5)
goto <x>;

<x<,

<x>: (. 3.8)

goto case;

case
switch (. 3.8)

goto case <x>;

case <x>
switch (. 3.8)

goto default;


d e f a u l t
switch (. 3.8)

if (>>) <>

<>, <s> (.
3.3)

i f (<s>) <,> e ls e <<

<:>, <> ,
<^>. else,
,
i f s t a t i c i f (. 3.3)

128

3.

3.1 ()

static if ('B>)<o/n>

<> ,
<> ,
</>.
</> { },
(. 3.4)

static if (<B')*o/*f,' else </2>


-s- /2>. else,
,
if static if (. 3.4)
return 'B>;

.
,

. <>
, - void
(. 3.10)

scope(exit) >>

<>,
(
return, -
).
scope (
failure success, .
) ,
(. 3.13)

scope(failure) <>

<>,

(. 3.13)

scope(success) <-

<>
( return
) (. 3.13)

switch ('S>) <>

<e>
case, <>
<> (. 3.5)

final switch (<s*) <>

,

,
case
(. 3.6)

synchronized (<s,*, >2>...)>>

>, ,
'S,>, <7> .., .
<e^
class (. 3.14)

129

3.16.

throw (<s>);

<s>

catch. <s>
Throwable (.
3.11)

try <> catch(<7^.> *,) -,- -- <>.


catch(<r> >) <> finally -,- ,
< f/,..., <> . - ,
<>.
( <>
) try
<wf>. catch
finally ( )
(. 3.11)
while (<s>) <>

<>, <s> (
,
<s> ) (. 3.7.1)

with (<a>) ->

<s>, <>,
<s>:
<>
, <s> (.
3.9)

4
,

,
( , ),
-.
, ,
, ,
, .

4.1.
D , .
T , T[ ] - ,
, . D
T[] - , .
new (.
2.3.6.1):

i n t [ ] array = new in t[ 2 0 ] ; / / 20
:

a u to array = new in t[ 2 0 ] ;

/ / 20

T[]
T.init ( 0).
,
array[n]:

a u to array = new in t[ 2 0 ] ;
a u to x = a rray [5 ]; / / 0 19

131

4.1.
a s s e r t( x == 0);

/ / :

/ / in t .init = 0
array[7] = 42;
/ /
a s s e r t( a r r a y [ 7 ] == 42);

, new, .
,
,
uniform std. random:
import std.random;
void main() {
/ / 1 127
auto array = new double[uniform(1, 128)];
foreach ( i; 0
a r r a y .le n g th ) {
a r r a y [ i ] = uniform(0.0, 1.0);

}
}
foreach ,
, (. 3.7.5):
foreach ( r e f element; array) {
element = uniform(0.0, 1.0);

>
ref ,
element .
.
(
) :
auto somePrimes = [ 2, 3, 5, 7, 11, 13, 17 ];

- .
.dup
:
auto array = new int[100];
auto copy = array.dup;
a s s e r t( a r r a y ! i s copy);
a s s e r t( a r r a y == copy);

/ / ,
/ /

, T[],
null,
(null array). ,
null true.
s t r i n g [ ] ;
a s s e r t( a i s n u ll);

/ / , s t r i n g [ ] = n ull

132

4. ,
a s s e r t ( a == n u ll) ;
= new s t r i n g [ 2 ] ;
a s s e r t ( a ! i s n u ll) ;
= a[0
0];
a s s e r t ( a ! i s n u ll) ;

/ / ,


: - null.

4.1.1.
.
.length :
auto array = new short[55];
a s s e r t ( a r r a y .l e n g t h == 55);

array.length
array. ,
[.11 - 1].
,

$.
auto a rra y = new in t[1 0 ];
a rra y [9 ] = 42;
a s s e r t ( a r r a y [ $ - 1] == 42);

4.1.8-4.1.10.

4.1.2.
, ?
auto array = new in t[1 0 ];
auto in v a lid = array[100];

, ,
,
. , - ,

.

- .

, , .

.
- .
, ,
, ,

4.1.

133

.
, ,
.


[58].
D
.
, , ,
,
.
, D
, .
D :

(. 11.2.2);

(non-release) (release)
(. 10.6).

D (safe) (system ) .
- (trusted).
, ,
.
- .

( ),
.
,
, .
( ,
),
:

@safe;

O Trusted;

@system;


( ).
11,
,
@safe, @trusted @system.

134

4. ,


. D

(-release ).
.
( ) .
,
assert (
10).
( / )
(/ ) . 4.1.
4.1.


( -release
dmd)

4.1.3.
- ,
. ,
:

Im po rt s t d . s t d i o ;
void main() {

a u to

array

[0,

1,

2, 3, 4, 5, 6, 7, 8, 9];

/ /
w rite ln (a rr a y [ S / 2
$]);

}
:
5 6 7 8 9

array, array[m.. n]
, m
n-1 ( ).
, , , ,
, :
array = array[S / 2

$];

, ,
$, ,

4.1.

135

, . m n ,
: .
> > .11 .
,
4.1.2.
array[0 .. $] ,
. ,
, array[0 .. $]
array[].

4.1.4.
( )
-
. ,
auto = [1, 5, 2, 3, 6];
, . 4.1.
, ;
.

. 4.1. ,

( ,
,
,
.
.)
(auto b = ),
( in t [ ] b; ... b = a;)
. . 4 .2 ,
b , .
, b ,
b, b.
. 4 .2 ,
b = b[1 . . $ - 2];

136

4. ,

. 4.2. auto b = ; .'


,

, b, -
(. 4.3).

.4.3. = b[l .. $ - 2];


, b,
() ,
. 4 .2 4 .3 , ,
:
i n t [ ] ar ray = [0 , 1, 2];
l n t [ ] su barray = ar ray [1 . . $];
a s s e r t ( s u b a r r a y . l e n g t h == 2);
s u b a r r a y [ 1 ] = 33;
a s s e r t ( a r r a y [ 2 ] == 33); / / subarray
/ / array

137

4.1.

4.1.5.
i s b (. 2.3.4.3)
true, b
.
.
b == != ( . 2 .3 .1 2 ).
auto = [ " h e llo '' ,
auto b = ;
a s s e r t ( a i s b); / /
a s s e r t ( a == b); / /
b = a.dup;
a s s e r t ( a == b); / /
//
a s s e r t ( a ! i s b); / /
//

"world"];
, b
,
, b ,

, b ,



==.

4.1.6.

, ^

.
,
,, 2.
: ( T[] T []),
( T[] T), ( T T[]).
i n t [ ] = [0 , 10, 20];
i n t [ ] b = ^ 42;
a s s e r t ( b == [0, 10, 20, 42]);
= b ^ ^ 15;
a s s e r t ( a . l e n g t h == 8);

4.1.7.
,
. ,
(
) [ ] [m .. n], :
auto = [ 0.5,
auto b = [ 3.5,

-0, 5, 1. 5, 2 ];
5.5, 4.5, -1 ];

138

4. ,
auto = new double[4]; / /
c [ ] = ( a [ ] + b []) / 2;
/ / b
a s s e r t ( c == [ 2 . 0 , 2 . 5 , 3 . 0 , 0 . 5 ]);

, 5;

, [] [m .. n], a[]
a[1 .. $ - 1];

D ,
, - ^,
+, -, *, /, %, ^^, ^, &, |, =, +=, -=, *=, /=, %=, ^=,
&= |=.

,
, ,

, .
,
auto = [ 1 . 0 , 2 . 5 , 3.6];
auto b = [ 4 . 5 , 5 . 5 , 1 . 4 ] ;
auto = new double[3];
c [ ] += 4 * a [ ] + b [];


foreach ( i ; 0

c .le n g th ) {
c [ i ] += 4 * a [ i ] + b [ i ] ;

}
,
4 .1.2.
( []
[m .. n]), ,

, :
double[] , b, ;
double d;
a [ ] = - ( b [ ] * ( c [ ] + 4 ) ) + c [ ] * d;


() :
i n t [ ] = new i n t [ 1 2 8 ] ;
i n t [ ] b = new i n t [ 1 2 8 ] ;
b[] = -1; / / b -1
a [ ] = b[]; / / b

139

4.1.


, ,
.
1- -
.
, (
), ,
. ,
,
- .

4.1.8.
,

. ;
, ,
, .
: :
auto

array = [0, 2, 4,
array = a rray [0
$ a s s e r t ( a r r a y == [ 0 , 2,
array = array[1
$];
a s s e r t ( a r r a y == [ 2 , 4,
array = array[1
$ a s s e r t ( a r r a y == [ 4 ] ) ;

6, 8, 10];
2];
4, 6 ] ) ;

//

//

//

6]);
1];

Bce ,
(
-).
- D. (
, ,
,
.) D
,
, ,
, ,
.
, ,
, , . , [5, 17, 8,
17, 5] - , [5, 7, 8, 7] - .
.
s t r i n g .
main, m ain (strin g [] args).

140

4. ,

s t r i n g
i n t , to
s td .c o n v . t o ! i n t ( s t r ) -
s t r i n t .
, ,
:
import std .c o n v , s td .s t d io ;
in t m ain(string[] args) {
/ /
a r g s = a r g s [1 .. $];
w h i l e ( a r g s . l e n g t h >= 2 ) {
i f ( t o ! i n t ( a r g s [ 0 ] ) != t o ! i n t ( a r g s [ S - 1 ] ) ) {
writeln("He " ) ;
r e t u r n 1;

}
args = args[1

$ - 1];

}
writeln("nannHflpoM");

r e t u r n 0;

}
,
.
( p alin d ro m e) :
p a lin d ro m e 34 95 548

[" 1^ " , "34, "95" "548"].


a r g s = args[1 .. $]:
a r g s [''34", "95", "548"].
. ,
: " " .
, a r g s .
t r u e , a r g s
(
), ""
.
, a r g s
. a r g s (
), .

4.1.9.
.
^=, :
a u to = [87, 40, 10];
^= 4 2 ;
a s s e r t ( a == [ 8 7 , 4 0 , 1 0 , 4 2 ] ) ;

141

4.1.
^= [ 5 , 1 7 ] ;
a s s e r t ( a == [ 8 7 , 4 0 , 1 0 , 4 2 , 5 , 1 7 ] ) ;

,
. :
a u t o = [ 8 7 , 40, 10, 2 ];
a u t o b = ;
/ / b
^= [ 5 , 1 7 ] ;
/ /
a [ 0 ] = 15;
/ / a [ 0 ]
a s s e r t ( b [ 0 ] == 1 5 ) ; / /
?


a[0] b[0]? , b
?
: b[0] 15, -
.
, ,

. .

,
^=,
^= b = ^ b, :
,
,
b,
. ,
. .
:
i n t [ ] ;
fo r e a c h ( i ; 0 ..
^= i ;

100) <

100 ,
,
.
, ,
^= b
, ,
. ,
, .
D ^=
:
, ,

.

142

4. ,

^=, , ,
,
.
.4 .4 ^= [5, 17].

. 4.4. a
,
, :


( , 2).
, 700 1024 ,
324 . ,
, ,
.
,

: , .
?
,
. (coalescing).

143

4.1.

-
.

, ,
,
.
, ,
.


. :
i n t [ ] = [0 , 10, 20, 30, 40, 50,
auto = a[4
$];
= a [0 .. 4];
/ / b
'= [0 , 0, 0, 0];
a s s e r t ( b == [ 4 0 , 5 0 , 6 0 , 7 0 ] ) ; / /
//

60, 70];

,
, , :
, b
, .
b
: b.
a s s e r t
, ,
.
, ,
,
, .

4.1.10. .length
. l e n g t h ,
, .
:
i n t [ ] array;
a s s e r t ( a r r a y . l e n g t h == 0 ) ;
a r r a y . l e n g t h = 1000;
a s s e r t ( a r r a y . l e n g t h == 1 0 0 0 ) ;
a r r a y . l e n g t h = 500;
a s s e r t ( a r r a y . l e n g t h == 5 0 0 ) ;

/ /
/ /

. l e n g th ,
. i n i t .

^= (. 4.1.9).

144

4. ,

.length,
D , . , n <=
a.length,a.len gth = = a[0 .. ].( ,
.)
,
.length :
a u t o a r r a y = new i n t [ 1 0 ] ;
a r r a y . l e n g t h += 1 0 0 0 ;
a s s e r t ( a r r a y . l e n g t h == 1 0 1 0 ) ;
a r r a y . l e n g t h / = 10;
a s s e r t ( a r r a y . l e n g t h == 1 0 1 ) ;

/ /
/ /

; , , ^ <o>= :
array.length = array.length <o> . - (
, ):
, , array - .

4.2.
D ,
. :
in t[1 2 8 ] someInts;

T n
T[n]: , uint[10] uint[11],
int[10].

, .
, ,
.
, . (
,
.)
s ta tic , ,
.
T[n]
T.init. :
i n t [ 3 ] ;
a s s e r t ( a == [ 0 , 0 , 0 ] ) ;

T[n] :
l n t [ 3 ] = [ 1 , 2, 3];
a s s e r t ( a == [ 1 , 2, 3 ] ) ;

4.2.

145

: i n t [ 3 ]
au to , D
i n t [ ] , i n t [ 3 ] .
i n t [ 3 ] , ,
i n t [ ] ,
,

, .
,
a u to . ,
, T[] , T[n]
n
( ).
T[n]
T,
.
i n t [ 4 ] = -1;
a s s e r t ( a == [ - 1 , - 1 , - 1 , - 1 ] ) ;


,
void:
in t[l0 2 4 ] = void;

, ,
,
. : ,
, ,
( ) .

a [ i ] , .

. , ,
1024 :
im port std.random ;
void main() {
double[1024] array;
foreach (i; 0
array.length) {
a r r a y [i] = uniform (0.0, 1.0);

>
}
,
:

146

4. ,
fo r e a c h ( r e f element; array) {
elem ent = uniform (0.0, 1.0);

>

4.2.1.
, ,
.
, .l e n g t h
. ,
, ,
, ,
:
i n t [ 1 0 0 ] q u a d r u p e d s 1;
i n t [ 4 * q u a d r u p e d s . l e n g t h ] l e g s ; / / , 4 00

a . l e n g t h
$,
.

4.2.2.

.
, , ,
, ,
. :
in t[1 0 ] array;
a r r a y [ 1 5 ] = 5; / / !
/ / 15 a [ 0

10]!


,
, ,
,
(. 4.1.2).

4.2.3.
T[n] T[]
:
i n t [ 5 ] a r r a y = [4 0 , 30, 20, 10, 0 ];
a u to s l i c e 1 = a r r a y [2 .. $];
/ / s l i c e 1 i n t [ ]
a s s e r t ( s l i c e 1 == [ 2 0 , 10, 0 ] ) ;
auto s lic e 2 = array[];
/ / , a r r a y [ 0
a s s e r t ( s l i c e 2 == a r r a y ) ;

1 quadrupeds (.) - . - . .

$]

147

4.2.


, .
T[n] ,
a1 a2, ,
, T[a2 - 1], . ( ,
au to , T[].) :
i n t [ 1 0 ] ;
i n t [ ] b = a[1
auto = a[1
i n t [ 6 ] d = a[1

7];
7];
7];

//
//
//


, in t [ ]
, a[1
7] d

4.2.4.
,
. , ,

. :
i n t [ 3 ] = [1, 2 , 3 ] ;
i n t [ 3 ] = ;
a[1] = 4 2 ;
a s s e r t ( b [ 1 ] == 2);
/ / b -
i n t [ 3 ] f u n ( i n t [ 3 ] x, i n t [ 3 ] ) {
/ / x -
x [ 0 ] = y [ 0 ] = 100;
r e t u r n x;

}
au to = fu n (a, b);
/ / i n t [ 3 ]
a s s e r t ( c == [ 1 0 0 , 4 2 , 3 ] ) ;
a s s e r t ( b == [ 1 , 2 , 3 ] ) ;
/ / f u n b


, .
,
. - ,
:
,
r e f T[] (. ).
,
. (
D ,

, .)
T[n] T[].
, ,
: .
,

148

4. ,

.
T[n] ,
T[]. ,
T[n],
T[].
d o u b l e [ 3 ] p o i n t = [0 , 0, 0];
d o u b le[] t e s t = point;
double[3] fun(double[] x) {
do uble[3] result;
r e su lt[] = 2 * x[];
return resu lt;

/ /

/ /

/ / ,

}
auto = fun(point);

double[3]

.dup
(. 4.1), T[n],
T[],
. ,
, - 1 copy = .

4.2.5.

i s ==, (. 4.1.5).

:
i n t [ 4 ] f i x e d = [ 1 , 2, 3, 4 ] ;
auto anotherFixed = fixed;
assert(anotherFixed ! is fixed);
a s s e r t ( a n o t h e r F i x e d == f i x e d ) ;
au to dynamic = f i x e d [ ] ;
assert(dynam ic is fixed );
a s s e r t ( d y n a m i c == f i x e d ) ;
dynamic = dynam ic.dup;
assert(dynam ic ! i s fixed );
a s s e r t ( d y n a m i c == f i x e d ) ;

/ / ( )
/ /
/ / f i x e d
/ /
/ /

4.2.6.
,
(. 4.1.6). .
,
.
. :
d o u b l e [ 2 ] ;
d o u b le[] b = ^ 0.5;

/ / d o u b le [ 2 ] ,
/ / d o u b le [ ]

149

4.3.

a u to = ^ 0 .5 ;
d o u b le[3 ] d = ^ 1 .5;
d o u b le[5 ] e

= ^ d;

//
//
//
//
//


,

,

^
,
: ,
.

4.2.7.

, (.
4.1.7).

.

4.3.
T[ ] T,
T[], , - , , T[][]
T[], .
, ,
, ,
. T[][] :

a u to array

new d o u b le [][5 ];

/ / ,
/ / double,
/ / - n ull

/ /

fo re a c h ( i, r e f e; array) {
e = new d o uble [a rray.le ngth

i] ;

>
:
d oub le, -
( 4), .
, ,
(jagged array),
( ,
). . 4 .5
.
,
, array[3][1] -
.

150

4. ,

. 4.5. ,
.
,
. ,

. ,

,
. , 1 0 0 0 0 0 0 ,
10 int, 2 0 0 0 0 0 0 (
- )
1 0 0 0 0 0 0 , ,
,
(
10 40 ).

.
- :

, - - .
- ,
, . -
-.
,
:
enum

s i z e _ t columns = 128;
/ / 64 128

4.4.

151

auto matrix = new d o u b le [c o lu m n s ] [ 6 4 ] ;


/ / -
fo reach ( r e f row; m a trix) {
.. / / d o u ble[co lum n s]

>

ref. - double[colum ns]
(. 4.2.4)
, , , .
,
,
, :

enum

s i z e _ t rows = 64, columns = 128;


/ / 64 128
d ou ble [c o lu m n s][ro w s] matrix;
/ / -
fo rea c h ( r e f row; m a trix) {
/ / dou b le [c olu m n s]

>
i j ,
m a t r i x [ i ] [ j ] 1. ,
( [][]),

. , [] [n]
, - .

, . ,
i n t [ 5 ] [ ] [ 1 5 ] - 15
, 5 i n t .

4.4.
,
()
( ).

1 ,
,
. , arr i n t [ 5 ] [ 5 ]
5 * 5 * i n t . s i z e o f , a r r[2 ][2 ]
&arr + 2 * 5 + 2.
(
static), ,
. - . . .

152

4. ,

[0; _ - 1 ]
( ).

.
() .
, . ,
,

, , ,
.
, V[K], , V - . ,
,
:
in t[ s t r i n g ]

aa = [ "":42,

" : 75 ];

(. 2.2.6) -
: ,
. ,
aa , :
auto

aa = [ "":42,

"":75 ];

4.4.1.
aa a a .l e n g t h s i z e _ t
aa ( , , ,
--).
, ( ),
,
n u l l t r u e .
s t r i n g [ i n t ] aa;
a s s e r t ( a a == n u l l ) ;
a s s e r t ( a a . l e n g t h == 0);
aa = [0 : 'zero", 1:''not zero''];
a s s e r t ( a a . l e n g t h == 2);

, .le n g th
.
,
nu ll.

4.4.

153

4.4.2.
aa -,
, ,
a a [ k e y ] 1, :
/ / /
aa = [ " ":" ^ ", "Mnp":"mundi" ];
/ /
[""] = "ciao";
[""] = "mondo";
/ / -
[""] = ''cavolo'';
[ "] = "mozzarella'';

auto

,
aa[key]. (
,
.) :
asse rt(a a ["3flpa B C T B y ti"] == "ciao");

,
, .
, , -
, ,
,
, .
g e t , .
aa.get(KnK)4, __) ,
, ___
; ___
.
assert(aa["3flpaecTByii"] == '^ciao'');
/ / "" ,
assert(aa.get("3flpaBCTBy^' " s a lu t e " ) == "cia o");
/ / "" ,
assert(aa.get("3fl0p0B0" "buongiorno") == "buongiorno");

,
, in 2:

1 V[K]
immutable(K) .
,
,
. - . ..
2 , in ,
, n u l l , . - .
. .

154

4. ,
a s s e r t ( "3ApaBCTsyki" in aa);
a s s e r t( ''3 iT ! in aa);
/ / a a [ "]

4.4.3.
-
:
.
:
auto a1 = [ "Jane":10.0, "Jack ":20, "Bob":15 ];
auto a2 = a1;
/ / 1 a2
a1["Bob"] = 100;
/ / a1,
a s s e r t ( a 2 [ 'B o b '] == 100); / /
.
a2.
a2["Sam"] = 3.5;
//
.
a s s e r t( a l[ 'S a m " ] == 3.5 ); / /

, ,
.dup, .

4.4.4.
is , == != , .
b
is b , b
(
). == b
- ==.
b , ,
.
auto a1 =
auto a2 =
assert(al
assert(al
a2["Bob"]
a s s e r t( a 1

[ "Jane":10.0, ''Jack":20, ''Bob":15 ];


[ "'Jane": 10.0, ''Jack":20, "Bob";15 ];
! i s a2);
== a2);
= 18;
! = a2);

4.4.5.
-,
remove, .
auto aa = [ "":1, ' ":2 ];
aa. '");
a ssert(" 3flp aBC TB yn " !in aa);
.(""); / / , . . aa ""

remove : true,
, fa lse.

155

4.4.

4.4.6.

foreach (. 3.7.5). -
:
import s td . s td i o ;
void main() {
auto coffeePrices = [
" : 262,
"" : 239,
" " : 224

];
foreach (kind, price; co ffee P rice s) {
writefln("%s %s . 100 "

kind, p r ic e );

>
}
:
2 62 . 100
239 . 100
22 4 . 100

. keys
. aa V[K]
aa.keys K[].
auto gammaFunc = [-1 .5 :2 .3 6 3 , -0 .5:-3.545, 0.5:1.772];
double[] keys = gammaFunc.keys;
a s sert(keys == [ -1.5, 0.5, -0.5 ]);

aa aa.values
aa V[].

foreach, .keys .values,

,
.
,
, :
aa.byKey()
aa, aa.byValue() -
. :
auto gammaFunc = [-1 .5 :2 .3 6 3 , -0 .5:-3.545, 0.5:1.772];
/ /
foreach (k; gammaFunc.byKey()) {
w riteln(k);

156

4. ,

4.4.7.
,
.
,
: toHash opCmp.
,
6.

4.5.
D . ,
( ),
. -, D
. ( -
.) -,
D UTF-8, UTF-16 UTF-32,

.
, D , -
UTF. ,
Unicode Explained [36]
, [56] , 5.1
, - .

4.5.1.
: ,
(code point), , (encoding).
, , ASCII
. ASCII
, , (
)
0 127, 7 .
ASCII, 8- (
) , ASCII . ( ,
1
.)

1 -


. - . .

4.5.

157

, , , ,
, ,
. 65, 8364 . . ,

, - ,
. ,

, ,
.
5.1
0 1114111 (
: 0x10FFFF, U+10FFFF
). , ,

, - ,
(,
,
). ,
17 6 5 5 3 6 ( ,
). ( ,
,
.)
, ,
.
,
0 1114111 .
,
.

.

4.5.2.
ASCII,
0x10FFFF ,
.
.


(),
. -
. (
)
, , (
).

158

4. ,

,
.

. ( 8-
16-) (code units).

.
,
, UTF-8. UTF-8,
- [47], -
.
UTF-8:
1 6 ; ,
.
127 UTF-8
ASCII. ASCII-
UTF-8, .
, ASCII, UTF-8
(. 4.2).
4.2. UTF-.
,
,

(
)
000000000000007F

0xxxxxxx

00000080-000007FF

110xxxxx 10xxxxxx

000008000000FFFF

1110xxxx 10xxxxxx 10xxxxxx

00010000001FFFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

0020000003FFFFFF

111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

040000007FFFFFFF

1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx


10xxxxxx


0x10FFFF,
;
.

:
1.
.
2. .

4.5.

159

,
. - :
UTF-8,
,
( , 10).
- :
UTF-8 ,
. UTF-8
(,
).
,
.

, - .
UTF-8
,
. ,
,
- .
UTF-16 ,
(, ) .
0 0xFFFF 16- ,
0x10000 0x10FFFF ,
,
0xD800 0xDBFF, - 0xDC00 0xDFFF.

0xD800-0xDBFF.
{high su rrogate area)
(low su rrogate area) .
UTF-16 ,

. , ,
-
(Basic M ultilingual Plane, BMP) -
UTF-16,
, UTF-16,
,
.
,
UTF-16 - UCS-2 (
16 ),
UTF-16,
,
--.

160

4. ,

, UTF-32 32
. , UTF-32
,
.
: UTF-8 ,
UTF-32 , ,
.

4.5.3.
D : char, wchar dchar,
UTF-8, UTF-16 UTF-32
. . in i t
: char.init OxFF, wchar.init - OxFFFF, dchar.
i n i t - 0x0000FFFF.
. 4 .2 , 0xFF
UTF-8, 0xFFFF
.
,

UTF-
( ,
),
char, wchar dchar - UTF-
. 8-, 16- 32-
, UTF,
ubyte, ushort uint . ,
8-
ubyte,
char.

4.5.4. + =
char[],
wchar[] dchar[] -
UTF-. , ,
, ,
.
, D ,
: s trin g , wstring dstring.
,
: immutable,
.
, s trin g - immutable(char)[].
( immutable)

4.5.

161

8, immut
able : s trin g ,
immutable(char)[],
char[] ( immutable(wchar)[] -
wchar[]), :
:
s tr in g = "hello";
char h = a[0]; / /
a[0] = 'H ' ;
/ / !
/ / immutable(char) !

- ,
s trin g , :
s tr in g = "hello";
= 'H' ^ a[1
$]; / / ,
/ / == 'Hello''

?

(, 4.1.6 ,
^ ),
.
immutable ,
, s trin g , wstring dstrin g ,
.
. :
s tr in g = ''hello";
s tr in g b = ; / / b ''hello"
s tr in g = b[0
4]; / / ''h e ll"
/ / , , b, :
/ / a[0] = 'H';
/ / b :
= 'H' ' a[1
$];
assert(a == "Hello" && b == "hello" && == ''hell ' );


, , ,
.
,
(,
).

- .
string ,
( ), ( ),

. UTF-,

162

4. ,

,
.
D ,
( ).
UTF- ; ,
'H' ^a[1 .. $] : ,
.
:
= 'H' ' a[stride(a, 0)

$];

strid e std .u tf
.
strid e -
:
import s t d . u t f ;

stride(a, 0)
( ) .
,
.

, (.
2 .2 .5). D

. :
import s t d . s t d i o ;
void main() {

string = " \u03bb \u20AC20.'';


wstring b = " \u03bb \u20AC20.";
dstring = " \u03bb \u20AC20.";
writeln(a, '\n' b, '\n' );
}
, b
, ,
, .
,
:
X = 2 0 .

,
.
, -
, UTF-8 UTF-16,
UTF-32 ( string, wstring dstring),
.

163

4.5.

,
, w d (, "_"):
UTF-8, UTF-16 UTF-32 (. 2.2.5.2).

4.5.4.1. foreach
str ( ) :
foreach (; s t r ) {
. . . / /

>

str. , str - char (
immutable ),
char. , ,
, .
, strin g,
.
void main() {
s tr in g s t r = ''Hall\u00E5, V\u00E4rld! ";
foreach (; s t r ) {
w rite ('[
, ' ] ' ) ;

}
w r i t e l n ( );

>
, :
[] [] [1] [1] [ Q ] [ Q ] [ . ] [ ] [V] [ Q ] [ Q ] [ r] [1] [d] [ ! ]

? (
) -
UTF-. ,
char,
char, .
,
. , dchar:
. , "dchar"
foreach (dchar ; s t r ) {
w r i t e ( ' [ ' , ']);

}

str ,
. :
[] [] [1] [1] [] [ , ] [ ] [V] [] [ r] [ 1] [d] [ ! ]

,
dchar, -

164

4. ,

. ,
wchar,
, ASCII,
UTF-16, (
).
, ,
dchar.
foreach

, . ,
dstring, (
) char.

4.6. -

, . -
: .
, .
- ,
,
.
T T*
null ( ).
&,
- * (.
2 .3 .6 .2 ). :
i n t x = 42;
int* p = &x;
*p = 10;
++*p;
a s s e r t ( x == 11);

//
//
//
//

x
*p , x

x p

,

. ,
, -
. n,
, ,
, n , n , , n
. p[n]
*(p + n). , 2 - 1 ,1 + n == p2.
arr
arr.ptr.

4.6. -

165

arr arr.ptr +
arr.length - 1,
- arr.ptr + arr.length.
:
auto a r r = [ 5, 10, 20, 30 ];
auto p = a r r . ptr;
assert(*p == 5);
++p;
assert(>p == 10);
++.p;
assert(>p == 11);
P += 2;
assert(^p == 30);
assert(p - a r r . p t r == 3);
:
( , ,
- ),
.
: - 1,
, ,
, .
.
, ,
( ):
auto x = 10;
auto = &x;
++; / / ...

, :
auto x = [ 10, 20 ];
auto = x.ptr;
+= 100;
/ / .
*y = 0xdeadbeef; / /

,
, -
: ,
, .
(m em ory-unsafe) .
,
, (. 6), ,
ref (. 5.2.1), -

1 xS6 4
(DW), short 2 . - .
. .

166

4. ,

. ,
.
, - ,
:

. ,
, -
; , , ,
,
.
,

. ,
, , ,
.
: .
, -
, .
,

, .
, ,
, , .
,
,
. .
D, SafeD (.
11), ,

.
, D (SafeD)
. - ,
, SafeD.

4.7.
. 4 .3
, . 4.4. -
, . 4 .5 - .

167

4.7.

4.3. (a b -
T[]; t, t t, ..., t T; n - ,
muny _{)

new T[n]

T[]

(. 4.1)

..... *J

T[]

; T t, (.
2.2.6 4.1)

=b

T[]

(. 4.1.4)

a[<fl*]

ref T

(
$ <> a.length, <e>
pa3Mep_t; ,
<> < a.length) (. 4.1)

a[-fl,* .. <Bj>] T[]

( $ <e,* -2> -length, >e,> 3>


pa3Mep_t,
<s/<=<flj> && 82 <=.1^)(.4.1.3)

a[]

T[]

(. 4.1.7)
a[0 .. $],

a.dup

T[]

(. 4.1)

a.length

pa3Mep_t (. 4.1.10)

a.length = n

pa3Mep_t (. 4.1.1)

is b

bool

, (.
4.1.5 2.3.4.3)

!is b

bool

, !( is b)

== b

bool

(.
4.1.5)

!= b

bool

, !( == b)

^t

T[]

(.
4.1.6)

t ^

T[]

(.
4.1.6)

^b

T[]

(. 4.1.6)

^= t

T[]

(. 4.1.6)

^= b

T[]

(. 4.1.6)

a.ptr

(
) (. 4.6)

168

4. ,

4.4. (a b -
T[]; t, t 1......t k T; n - ,
muny pa3Mep_t)

[t,...... tJ

T[k]

, T[k]
; T t, (. 2.2.6 4.1)

= b

ref T[n]

(.
4.2.4)

a[<e>]

ref T

(
$ <e> a.length, <s> pa3Mep_t; , <> < a.length) (. 4.1)

a[>fl,' .. <s2>] T[]/T[k]

( $ <s,> <s2> eTCHHaa.length, <s,> <2>


pa3Mep_t,
<fl/ <= <8> && <2> <= .1^)(.4.2.3)

a[]

T[]

(. 4.1.7)
( )
, , a[0 .. $]

a.dup

T[]

(. 4.2.4)

a.le ngth

pa3M ep_t

(. 4.2.1)

is b

bool

, (.
4.2.5 2.3.4.3)

!is b

bool

, !( i s b)

== b

bool

(.
4.2.5 2.3.12)

!= b

bool

, !( == b)

^t

T[]

(.
4.2.6)

t ^

T[]

(.
4.2.6)

^b

T[]

(. 4.2.6)

a.ptr

T*

(
)

169

4.7.

4.5. (a b
V[K]; , k^,..., k^ ; v, vf..... vk
V)

[ t , :v, .... t , : v J

V[K]

;
k,, V - v, (.
2.2.6 4.4)

= b

V[K]

b
(.
4.4.3)

a[k]


( k ,
) (. 4.4.2)

a[k] = v

k v (
,
) (. 4.4.2)

k in

V*

k , null, ,
- ,
k (. 4.4.2)

k !in

bool

,!( in )

a.length

pa3Mep_t

,
(. 4.4.1)

is b

bool

,
(. 4.4.4 2.3.4.3)

!is b

bool

, !( i s b)

== b

bool


(. 4.4.4 2.3.12)

!= b

bool

, !( == b)

a.remove(k)

bool

k, ;
tr u e , k
(. 4.4.5)

a.dup

V[K]


(. 4.4.3)

a.get(k, v)

,
k;
v (. 4.4.2)

a.byKey()

in t deleg a te(in t ,
delega te(ref K)) foreach

a.byValue()

i n t deleg a te(in t ,
delegate(ref V)) foreach

5
.

,
, - 1970-e. , ,
, , ,
, . , -
.
, ,
-; , , , , -
, ,
.

.
,
- :
- ,
,
.
D
;
,
, . D,
, ,
.
, .

5.1.

171

5.1.

: ,
( ), -
. - .
- . ( -
? .) -... , .
, , , ,
,
- . ,
. ,
.
, ,
: , ,
, -, , ,
- , ...
,
D,
. ,
, , in t
int.
bool find(int[] haystack, int needle) {
foreach (v; haystack) {
i f (v == needle) return true;
}
return false;

}
. D,
, .
find,
.
find haystack needle1
. ,
,
; 4, in t[] (
int), (fa tp o in ter),
+ +
, .
4.1.4 , find
,
. ( D

1 find (needle) (haystack). - . .
.

172

5. .

, , ,
.
.) find
.
find,
( ),
. ,
, - :
, .
, find - .
bool, ;
, ,
. ( -
, -1, ).
,
,
( ).
n- ,
find n, ,
- ,
!
- , .
, , .
, find
(?) (haystack),
, , haystack. (,
, find haystack.)
: find(haystack, needle)
haystack , needle
, , haystack,
haystack.
in t[].
i n t [ ] f i n d ( i n t [ ] haystack, i n t needle) {
while (h aysta ck.le ngth > 0 && haystack[0] != needle) {
haystack = haystack[1
$];

>
retu rn haystack;

: find
haystack
.
, , ,
. ,
find.

5.2.

173



. ,
.
,
find. ( )
( )
find:
unittest {
i n t [ ] = [];
a s s e r t( f i n d ( a ,
= [ 1, 2, 3
assert(fird (a,
a s s e r t( f i n d ( a ,
a s s e r t( f i n d ( a ,
a s s e r t( a [ 0

5) == [ ] ) ;
];
0) == [ ] ) ;
1 ).le n g th == 3);
2 ) .le n g th == 2);
$ - find(a, 3 ) .le n g th ] == [ 1, 2 ]);

}
, , , -
searching.d,
:
$ rdmd - - m a i n - u n i t t e s t

searching.d

-u n ittest,

. u n ittest,
,
. --main
rdmd main. (
--main, ;
- .)
main ,
, .
,
, main.

5.2.

, find (
- in t, ,
in t[]), .
find ,
.
. ,
* ,
. - :

174

5. .

, ,
. :
void f u n (in t x) { x += 42; }
void g u n ( in t[ ] x) { x = [ 1, 2,
void h u n ( i n t [ ] x) { x[0] = x[1];
u n itte st {
i n t x = 10;
fun(x);
a s s e r t( x == 10);
i n t [ ] = [ 10. 20, 30 ];
gun(y);
a s s e r t ( y == [ 10, 20, 30 ]);
hun(y);
a s s e r t ( y == [ 20, 20, 30 ]);

3 ]; }
}

/ /

/ /
/ / !

}
? fun gun
. ,
,
.
hun ,
. , ,
, ,
. , - x = [1, 2, 3], ,
x,
, x ; - x[i]
x, , ( , fun), .

5.2.1. ,
( ref)
,
. ref:
void bump(ref i n t x) { ++x; }
u n ittest {
i n t x = 1;
bump(x);
a s s e r t ( x == 2);

}
,
, . ,
1-, . :
bump(5); / / 01 r -

- , ,
.

5.2.

175

ref .
1-. ,
bump :
ref i n t bump(ref i n t x) { return ++x; >
u n ittest {
i n t x = 1;
bump(bump(x)); / / 1
a s s e r t( x == 3);

)
bump 1-,

. bump
:
i n t bump(ref i n t x) { return ++x; }

bump(bump(x))
-, bump(x), ,
bump.

5.2.2. ( in)
in
, . :
void fun(in i n t x) <
x = 42;
/ / ! in

}
, in
. fun
.
, ,
,
. in
, ,
,
.
, ,
. :
void fun(ln i n t [ ] data) {
data = new in t[1 0 ]; / / !
data[5] = 42;
/ / !

>
, ,

int. , .

176

5. .

in data - in
.
, , ,
.
:
/ /
void fun (in i n t [ ] [ ] data) {
d ata[5 ] = data[0 ];
/ / !
d a ta [ 5 ][ 0 ] = d a ta [0 ][5 ]; / / !

}
in , ,
1.
, D.
, in -
const2, 8.

5.2.3. ( out)
,
- .
out, ref, - ,
out
( ):
/ / b.
/ / no , - rem.
i n t divrem (int , i n t b, out i n t rem) {
a s s e r t ( b != 0);
rem = % b;
retu rn / b;

}
u n ittest {
i n t r;
i n t d = divrem(5, 2, r);
a s s e r t ( d == 2 && r == 1);

,
, ,
, . :
( c a s t( in t[ ]) d a ta ) [5 ] = 42; , . . - . ..
, in scope const, scope
, , scope . . . .

5.2.

177

out
ref, out
, divrem rem
.

5.2.4. ( lazy)1

,
. :

bool verbose; / / ,
void lo g ( s tr in g message)
{
/ / ,

i f (verbose)
writeln(message);

i n t r e s u lt = foo(); lo g ("foo () returned '' ^ t o ! s t r i n g ( r e s u l t ) ) ;


. '^ () returned " ^ to!strin g(resu lt)
, verbose true.
, ,
.
,
. , ,
verbose fa lse
! ,
( 5.6.1):

void lo g ( s tr in g d e le g a te ( ) message)
{

i f (verbose)
writeln(m essage());

>
.lo g ({ retu rn "foo() returned " ^ t o ! s t r i n g ( r e s u l t ) ; }>;

,
, . D
, .
lazy, ,
, .

void log(lazy s tr in g message)


{

1 ,
,
. - . . .

178

5. .

i f (v e rb o se )
w rite ln (m e ss a g e ); / / m essage
}

5.2.5. ( static)
s ta tic
, , ,
ref, s ta tic ,
.

s ta tic .
.

s t a t ic -
13.

( ).

, .
s ta tic ,
private.

s t a t i c i n t z e ro s; / / , p r iv a te i n t zero s;
vo id f u n ( i n t x) {
s t a ti c in t c a lls ;
+ + c a lls;
i f ( ! x ) ++zeros;
>
1,
.

,
:

v o id fu n (d o u b le x) {
s t a t i c d o u b le m inInput;
s t a t i c bool m in I n p u tI n itia liz e d ;
i f ( ! m in I n p u tI n itia liz e d ) {
m in Inpu t = x;
m in I n p u tI n itia liz e d = tr u e ;
} e ls e <
1

, ,
(
). - . . .

5.3.

179

i f (x < minInput) minInput = x;

}
>

5.3.
find, 5.1,
. -,
,
. .
find int - , .
,
double double[] string
strin g[]. int
- find, ,
. ,
:
T[] find(T)(T[] haystack, T needle) {
while (haystack.length > 0 && haystack[0] != needle) {
haystack = haystack[1
$];

>
return haystack;

}
, find ,
. :
,
,
.
int, (,
).
unittest ,
T . !
,
:
unittest {
/ /
double[] d = [ 1.5, 2.4 ];
a s s e r t ( f in d (d , 1.0) == n u ll) ;
a s s e r t( fin d (d , 1.5) == d);
s t r i n g [ ] s = [ ''one" "two" ];
a s s e r t ( f i n d ( s , "two") == [ "two" ]);

}
,
find?
, in t[], T

180

5. .

- .
-, -
==. ,

.

[43]:

: ,
find,
.

: find
(int, double, string ..)
find .

,
,
find. ,
find
, ,
. ,
, ,
. , .
,
, - -
;
.
, , .
, , , .
- ,
( -
[];
- ,
).
:
,
, -
. (
) ,
.
, ,
, .
, , .

, ,
.

5.4.

181

D (,
)
. , ,
find, D
, ,
- , -
find.
find , ,
.
(), ,
.
find
, .
, -
find.
, find -
, : ,
find , . ,
.

5.4.
, double,
. ,
:
double[] = [ 1.0, 2.5, 2.0, 3.4 ];
= find(a, 2); / / ! f ind(doubl e[ ], i n t )

. find
T[ ] T
. find double[]
int, T = double T = i nt .
, , , ,
T double
,
i nt double.

, - ,
D . T[ ] T,
double[] i nt.
, find ,
,
.
,
==.

182

5. .

- , - :
T[] find(T, E)(T[] haystack, E needle) {
while ( haystack. length > 0 && haystack[0] != needle) {
haystack = haystack[1
$];

>
return haystack;

>
.
find , ,
T E, ! ,
,
:
a s s e r t ( f i n d ( [ 1 , 2, 3], "Hello")); //!
/ / haystack[0] != needle i n t [ ] str ing

;
, find.
, ,
: find . ( ,
, ,
find.)
,
. . ,
? , find ,
.
( {)
find , T
E. , p a e f i n d e c c c e e a p y e , y c a a a e ( T = int
E = st ri ng) .
find, ,
haystack[0] != needle,
:
find , . find

T E - , .
- . D
: find
.
- find, , T E
. D
(sig n a tu re co n stra in t):
T[] find(T, E)(T[] haystack, E needle)
i f ( ls ( typ eof (hay s t a ck[ 0] != needle) == bool))

183

5.5.
/ /

>
i f , find
haystack T[ ] needle E,
haystack[0] != needle .
. -, i f
, ,
find ,
( , ).
-, i f find
,
, , ,
, . -,

: ,
find, .
, , typeof,
;
, . (
typeof , ,
,
, - bool.) ,
, haystack[0],
haystack . :
,
; , find needle > 0.

5.5.
find, .
find, ,
.
- , .
:
.
,
.
, .
, :
T1[] find(T1, T2)(T1[] longer, T2[] s hor te r )
i f ( i s ( typ eo f (l o nger [0
1] == s h or te r ) : bool))

{
while ( l onger . l ength >= s h o r t er . l e n g t h ) {
i f (longer[0
s h o r t e r . l e n g t h ] == s hor te r ) break;
longer = longer[1
$];

>

184

5. .

return longer;

}
AraI , -
.
:
/ / ! !
bool f ind(T)(T[] longer, T[] s ho r te r ) {

)
, , , .
, , ,
int long, double -
flo a t.
. ,
,
.
,
!
,
longer ( ).
- longer[0
shorter,
length] == shorter, shorter.length
longer shorter.
D :
,
.
, .

, .
,
,
. ,
, ,
, .
, , ,
,
, . D
,
: (
if) fa lse ,
- .
find if
(
). find
; ,

5.5.

185

. ,
:
unittest {
/ / , find
double[] d1 = [ 6.0, 1.5, 2.25, 3 ];
f l o a t [ ] d2 = [ 1.5, 2.25 ];
a s ser t ( fi nd(d1, d2) == d1[1
$]);

>
, find:
; ,
i f
. ,
, i n t [ ]
find:
i n t [ ] f i n d ( i n t [ ] longer, i n t [ ] s h o r t er ) {

}
find .
, , find,
,
.

?
i n t [ ] ints1 = [ 1, 2, 3, 5, 2 ];
i r t [ ] ints2 = [ 3, 5 ];
auto t e s t = f i n d( i nt s 1 , i n t s 2 ) ; / / ?
/ / ?

D :
.
;
, , .
;
(p a r tia l orderin g of fu n ction s).

5.5.1.

, - ,
- .
<
, .
, foo, foo2, , foo,
, foo2 ( foo, ,
foo2 foo, < foo2). ,

186

5. .

, ,
:
foo
< foo.
,
( < ), ( < b b < ,
, b ) ( < b b < , < ).
D
: foo,
foo2, foo, < f 0 0 j. , foo, < foo2 foo2 < foo,
; ,
:
/ / :
/ /

void sqrt(real);
void sqrt(double);
void sqrt(float)
,
f lo at , double real (
, , ,
. 2.3.2).
, < ;
, foo, foo2 .1
, :
/ / :
/ / ,

void print(double);
void print(string);
,
foo, < foo2 foo2 < foo,.
, , foo, ,
foo2. :
/ / : write(double) ,
/ / w r i t e ( i n t ) , int,
/ / double.

void write(double);
void w r i t e ( i n t ) ;
D
^(,, ..., )
:
1 .
( < )
.

5.5.

187

1. (
), .
2. {fool.......... fooJ,
,
.
.
3. ,
.
4.
, .
5. ,

; .
6. ,
.
7. - .
. :
void transmogriFy(uint) {}
void transmogrify(long) {}
unittest {
transmogrify(42); / / t ransmogri fy(uint)

>
, ,
.
, , ,
, . (
, i n t uint.)
:
/ / To , ,
void transmogrify(T)(T value) {}
unittest {
transmogrify(42);
/ / , t ransmogri fy(ui nt )
t r ansmogri fy("hel l o"); / / transmogri fy(T), T=string
transmogrify(1.1);
//BtJ3bmaeTtransmogrify(T), T=double

}
, transmogrify(uint)
transmogrify(T)(T) ?
, T = int, T int,
. transmogrify(uint)
T? , .
, transmogrify(T)(T) ,

188

5. .

transmogrify(uint),
. ,
,
.

5.5.2.

.
uint long ( ,
):
/ / ca lv i n . d
void transmogrify(long) { . . .
/ / hobbes.d
void t r ansmogri fy( ui nt ) { ..

}
}

/ / c l i e n t . d
import calvin, hobbes;

unittest {
transmogrify(42);

}
transmogrify(uint) hobbes.d
;
, . D
. ,

( ,
, ).
:
import - !
, ,
: , ,
, ,
, -
. :
, transmogrify(5)

. -
, ,
.
,
.
, -
.
.
,

189

5.5.

, .
, .
:
/ / cal vi n. d
void transmogrify(long) { ..
void t r ansmogri fy(uint) {

}
}

/ / hobbes.d
void transmogrify(double) {
/ / susi e. d
void t r ans mo gr i fy( in t [ ]) {
void t r a nsmogri fy( st r i ng) {

>
}

/ / c l i e n t . d
import calvin, hobbes, susie;

unittest {
transmogrify(5);

//
//
calvin. tr ansmogrif y( 5); / /
//
transmogrify(5. 5);
//
//
transmogrify(''npnBeT"); / /

! ,

calvin hobbes.
, ,
c a l v i n. tr a n s m o g r i f y ( ui n t )
, hobbes
.

}
, .
,
;
calvin.d hobbes.d, ,
: ,
. ,
susie.d
(
1).


-
,
. - ,
,
calvin ,transmogrify(5). , calvin.d.
. -
. :
1
. - . .

190

5. .
/ / ca l v i n . d
Import hobbes;
a l i a s hobbes.transmogrify transmogrify;

:
transmogrify hobbes.d calvin.d.
calvin.d ,
, , ,
, hobbes.d.
calvin.d:
hobbes.d , , trans ^ . , ^ hobbes.d
,
clien t.d transmogrify,
( calvin.transmogrify, hobbes.
transmogrify).
/ / c l i e n t . d
a l i a s ca l vi n. tr ansmogr i f y transmogrify;
a l i a s hobbes.transmogrify transmogrify;

transmogrify clien t.d


, trans
mogrify, calvin.d hobbes.d,
clien t.d .

5.6. .

, .
.
:
. ,
.
find , ,
, ;
( ==).
find
.
find ,
, ,
.
,
, ,
,
. find ,
-.

5.6. .

191

T[] f i n d ( a l i a s pred, T)(T[] input)


i f ( i s ( t y p e o f ( p r e d ( i n p u t [ 0 ] ) ) ==

b o o l))

{
f or (; input. length > 0; input = input[1
i f <pred( i n p u t [ 0 ] )) break;

$]) {

>
return input;

}
find
, - a lia s
pred. -
: , , ,
. ,
find.
unittest {
i n t [ ] = [ 1, 2, 3, 4. -5, 3, -4 ];
/ /
auto b = find!( f unotion bool ( in t x) { return x < 0; })(a);

}
find .
!(...)
. .
: find
(alia s pred T),
. ,
: ,
= int. find
- :
.
pred ,
. -
function bo ol ( int x) { return x < 0; }

function - , -
, .
(
, -) ,
. 41 ,
5 .
, D .
- :
, ,
.
auto b = f i n d ! ( function(x) { return x < 0; ) )( a) ;

192

5. .

- function.
, (
):
auto b = f i n d ! ( ( x ) { return x < 0; })(a);

,
.

5.6.1.

-:
, -.
:
unittest {
i n t [ ] = [ 1, 2, 3, 4, -5, 3, -4 ];
i n t z = -2;
/ / z
auto b = f i n d !( ( x ) { return x < z; })(a);
a s s e r t ( b == a[4
$]);

}
, .
, ,
, !
auto b = f ind !( f un c t i on ( x) { return x < z; ) )( a) ;
/ / ! !

? ,
- ,
z
.
- ,
. ,
, z.
,
, .
, D ,
.
, :
unittest {
i n t z = 3;
auto b = f i n d ! ( de l e g a t e ( x) { return x < z; })(a); / / 0K

}
,
. function delegate,
, .

5.7.

193

,
, ,
.
a u t o f = ( i n t i) { } ;
a s s e r t ( i s ( f == f u n c t i o n ) ) ;

5.7.
find
, .
,
(
). find
( ); ,
,
. D ,
.
,
, ,
. :
void tr a n sm o g r ify (in t[] input, in t z) {
/ /
bool isT ra n sm o g rifia b le(in t x) {
i f ( x == 4 2 ) {
t h r o w new E x c e p t i o n ( " 4 2 " ) ;

}
r e t u r n x < z;

}
/ / i n p u t
i n p u t = f i n d ! ( i s T r a n s m o g r i f i a b l e ) ( i n p u t );
/ / . . .
input = f i n d ! ( is T r a n s m o g r if ia b l e ) ( in p u t ) ;

}
.
, ,
,
, ,
. ;
,
z .
, (
), isTransmogrifiable
, z.
,

194

5. .

i s T r a n s m o g r i f i a b l e ,
( t r a n s m o g r i f y ) .
i s T r a n s m o g r i f i a b l e s t a t i c (
?):
void tr a n sm o g r ify (in t[] input, in t z) <
s t a t i c i n t w = 42;
/ /
s t a t i c bool isT ransm ogrifiable(int x) {
i f ( x == 4 2 ) {
t h r o w new E x c e p t i o n ( " 4 2 ");

}
r e t u r n x < w; / / z

}
>
, s t a t i c , i s T r a n s
m o g r i f i a b l e , ,
t r a n s m o g r i f y ,
s t a t i c ( w ) . ,
,
, (, ,
).

5.8.
, a l i a s ; ,
, - .
p r e d - ,
; p r e d .
(,
), a l i a s . , ,
, ,
.
, , : x
T, , , x ,
. ,
:
, , .
, ()
, , , T [ ]
T [ ] . , ,
, - T [ ] d e l e g a t e ( T [ ] ) . d e l e g a t e , f u n c t i o n ?
,
, ,

195

5.8.

.
, - x.
, . , [] function(T[]) - (
).
.
,
. ,
(callbacks) - ,
, - :
.
, ,
, - void* (
), .
, MFC,

, , A ctive Template Library (ATL),
. ,
,
,
; .
delegate .
:
.
, .

, . ( , function
.)
, ,
- finder. , T[] delegate(T[]).
import s t d . algorithm ;
T[] d ele g a te (T []) fin d er(T )(T x)
i f ( l s ( t y p e o f ( x == x ) = = b o o l ) )

{
return d e le g a t e ( T [ ] ) { return f in d ( a , x);

};

}
unittest {
auto d = fin d er(5);
a s s e r t ( d ( [ 1 , 3 , 5, 7, 9 ] ) == [ 5, 7 , 9 ] ) ;
d = finder(10);
a s s e r t ( d ( [ 1 , 3 , 5, 7 , 9 ] ) == [ ] ) ;

}
, , return
, . ,

196

5. .


.
finder : T,
[] delegate(T[]);
, T : T
, . (
, x == x ,
- .) finder
, . ,
find,
.
(closure).
finder :
,
. d, ,
T[] delegate(T[]), auto
. , ,
auto finder;
.
finder:
auto f i n d e r ( T ) ( T x) i f (is(typeof(x == x) == bool)) {
return ( T [ ] ) { return f i n d ( a , x); };
>
auto
, , delegate
; .
T[ ] .
- , ,
auto:
find(a, x), , ,
x;
T[] delegate(T[]), finder.
.

5.8.1. , ... , ...


, !
u n ittest
finder, , , .
: finder
x, x , finder
? ,
( D
): finder, x
, finder ,
finder... ,

5.9. . .

197

f i n d e r ,
!
(
x,
) - ,
, , - .
D 1.
. ,

,
.
.
, f i n d e r
.

,
.

5.9. . .
5.3 : f i n d
, . ,
f i n d , ,
.
, .
?
, ,
. ,
(,
f i n d T [ ]),
. (
.) T [ ] ,
f i n d
, . ,
, , f i n d A r r a y
(), .
, ;
, .
, f i n d .
:
T[] find(T)(T[] haystack, T needle) {
while (haystack.length > 0 && haystack[0] != needle) <
1 ML
.

198

5. .

h a y sta c k = h ay stac k [1

$ ];

re tu r n h a y stac k ;
>
h a y s ta c k
?

1 . h a y s t a c k .l e n g th > 0 , 1 .
2 . h a y s ta c k [ 0 ] h a y s ta c k .
3. h a y s ta c k = h a y s ta c k [ 1 .. $] h a y s ta c k .
, ,
. ,
h a y s t a c k .l e n g th > 0,
, - , 1.
(
),
, ,

. -
. ,

h a y s ta c k .
, :

1 . h a y s ta c k .e m p ty h a y s ta c k .
2 . h a y s t a c k .f r o n t - h a y s ta c k .
3. h a y s ta c k .p o p F r o n t( )
h a y s ta c k .
: h a y s ta c k
, h a y s ta c k ,
().
f i n d , :

R fin d (R , T)(R h a y stac k , T n e e d le )


i f ( is ( ty p e o f ( h a y s ta c k .f r o n t != n e e d le ) == b o o l))
{

w h ile (!h a y s ta c k .e m p ty && h a y s ta c k .f r o n t != n e e d le ) {


h a y s ta c k .p o p F ro n t();
}

r e tu rn h a y stac k ;
}

- , ,
,
(
). - . .

5.9. . .

199


, : .
, T[]
,
empty, front
popFront. T[]. ,
,
,
, .

5.9.1. @property
,
(),
: .() .,
.
,
- , T[] - . ?
D
:
.(, , ), , (, b, , d)1
. (
: (, b, , d)
, .(, , d) .)
-
- --.
, empty, front popFront
. :

0 p ro p e rty bool e m p ty (T )(T [] ) { re tu rn a .le n g th == 0; }


0 p ro p e rty r e f T f r o n t( T ) ( T [ ] ) { r e tu rn a [0 ]; }
void p o p F ro n t(T )(re f T [] ) { = a[1
$]; }
@property ,
^property). @
,
. ,
2. ,

,
2 .0 5 7
, - . (7).som eprop() void so m eprop (int a){} ,
someprop i n t. - . ..
2 2 .0 5 7 ,
. . - . ..

200

5. .

property ,
, , () .1

ref (. 5.2.1). -,
front; ,
, . , ref
popFront,
.

find ,
; find ,
,
empty, front popFront, ,
,
. T
(inlining)2, find
, ,
.
empty, front popFront
find,
. , find,
empty-front-popFront,
,
? , ,

. ,

[27]; ++ STL [5] ,


. @ property
, .
,
.
-p ro p e rty (dmd 2 .0 5 7 ).
, , , , @ 1. . ..

( in lin e - ) -
.
, , ,
. C 99
, C 9 9 + + inlin e i n lin e -
, . D
i n l i n e - .
, , - . - . ..

201

5.9. . .

: ,
, ,
.
D ,
, - (range). (
,
,
.) D
, STL (
D STL);
D ,
STL. , empty-front-popFront
(input range);
find
:
,
,
, (
,
). find
std.algorithm .

5.9.2. -
, ?
: reduce1,
, fun x,
x = fun(x, e) e x.
reduce ,
. ,
.
accumulate, compress, in ject, fold l . .
reduce -
:
unittest {
i n t [ ] r = [ 10, 14, 3, 5, 23 ];
/ /
i nt sum = reduce!((a, b) { return + b; })(0, r);
assert(sum == 55);
/ /
i nt min = reduce!((a, b) < return < b ? : b; ) ) ( r [ 0 ] ,
assert(min == 3);

1 R e d u c e ( .) , . - . . .

r);

202

5. .

, reduce - ,
:
. reduce ,
. ,
,
reduce: 5.3 ,
; 5.4 reduce ,
; 5.6
,
-;
.
V r educ e( al i as fun, V, R)(V x, R range)
l f ( i s ( t y p e o f ( x = fun(x, r an ge .f ro nt ) ) )
&& i s(typeof(range. empty) == bool)
&& i s( t y pe of ( ra n g e . p o p Fr on t( )) ) )

{
f o r (; !range.empty; range.popFront()) {
x = fun(x, r ange . f ront ) ;

}
return x;

}
, , ,
.
reduce,
. , ,
, R ?
- . ,
std. range,
, reduce:
import std. range;
V r educ e( al i as fun, V, R)(V x, R range)
i f (isInputRange!R && i s ( t y pe of ( x = fun(x, r a n ge . f r o nt ) ) ) )

{
f o r (; !range.empty; range.popFront()) {
x = fun(x, r ange. f ront) ;

}
return x;

}
.
reduce, ,
, ,
,
. reduce std.algorithm
, ,
,

203

5.10.

;
,
.

5.10.
Hello, world!,
,
writeln .
: .
D
,
. .

5.10.1.

,
, :
import s t d . a l g o r i t h m ,

s t d .a r r a y ;

/ / ,
/ / ,
double a v e r a g e ( d o u b l e [ ] v a l u e s .
) {
i f ( v a l u e s .e m p t y ) {
throw new Exception("CpeflHee
" ");

>
return r e d u c e ! ( ( a , b) { return + b; } ) ( 0 . 0 ,
/ v a lu es.len gth ;

values)

}
u n lttest {
a s s e r t ( a v e r a g e ( 0 ) == 0);
a s s e r t ( a v e r a g e ( 1 , 2 ) == 1 . 5 ) ;
a s s e r t ( a v e r a g e ( 1 , 2, 3) == 2);
/ /
d o u b le [] v = [1 , 2, 3];
a s s e r t ( a v e r a g e ( v ) == 2);

}
( reduce.)
average: ... values,
. (
values average,
.)
average double (
) .

204

. .


,
double.
average.
,
, average(a, b, ) average([a, b, c]).

. :
/ /
dou ble a v e r a g e ( ) {}
dou ble a v e r a g e ( d o u b l e ) {}
/ /
dou ble a v e r a g e ( d o u b l e [ ] v a l u e s .
) { / , * /

>

unittest {
average();

/ / ! !

}
average
ave
rage .
, average([1, 2]).

- , ,-
, ,

:
import

std .std io ;

v o i d a v e r a g e ( d o u b l e [ ] ) { w r i t e l n ( ' ' c "); }


void a v era g e (d o u b le[].
) { w r i t e l n ( " c ); }
v o i d m ain() {
a v e r a g e ( 1 , 2, 3 ) ;
/ / ''c ''
a v e r a g e ( [ 1 , 2, 3 ] ) ; / / " "

}

(
) 1. 6,

.
E ^H H anncaT bvoid foo(T ]...), - , ^
T, 1 ,

, . - . ..

205

5.10.

, .
T , .
,
, .

5.10.2.

writeln.
, average, writeln
.

, :
import s t d . c o nv ;
voi d w r i t e l n ( T . ) ( T a r g s ) {
f or ea c h (arg; a r g s ) {
stdout.rawWrite(to!string(arg));

}
s t d o u t . r a wWr i t e ( ' \ r T);
stdout.flush();

}
, .
T writeln (,
), args - . foreach
, args - , ,
,
foreach (, foreach
). , , :
writeln("ne4aTaK) : ''

42,

" :

[ 1, 2, 3 ] ) ;

foreach
:
/ /
voi d w r i t e l n ( s t r i n g a0, i n t a1, s t r i n g a2,
s t d o u t . r a wWr i t e ( t o ! s t r i ng ( a O ) ) ;
s t d o u t . rawWrite(to!string(a1));
st d o u t . rawWrite(to!string(a2));
s t d o u t . rawWrite(to! s t r i n g ( a 3 ) ) ;
s t d o u t . r a w W r i t e ( ' \ n ' );
stdout.flush();

i n t [ ] ) {

}
std.conv to!string (
string, to!string -
), ,

.

206

5. .


foreach. n
, T[n] n- , args[n] - n-e
.
T.length args.length ( ,
).
, , ,
[$ - 1] T ( args[S - 1] args). :
i mport s t d . s t d i o ;
void te st i n g (T .

)(T v a l u e s ) {

writeln("riepeAaHHbix : "

v a l u e s . l e n g t h , '' ");
/ /
f or e a c h ( i , val ue ; v a l u e s ) {
w r i t e l n ( i , ":
t y p e i d ( T [ i ] ) , '' , v a l u e ) ;

}
}
v o i d mai n( ) <
t e s t i n g ( 5 , ""

4.2);

}
:
: 3 .
0 : in t 5
1: i m m u t a b l e ( c h a r ) [ ]
2: d o u b l e 4 . 2

5.10.2.1.
writeln ,
: \n'
flush .
writeln write,
:
i mport s t d . c o n v ;
v oi d wr it e( T. . ) ( T ar gs) {
f o r e a c h (arg; a r g s ) {
stdout.rawWrite(to!string(arg));

}
}
void writeln(T.
)( T a r g s ) {
write(args, '\n');
stdout.flush();

5.10.

207

, writeln args \n'


write.
, writeln(1, "2", 3) write
, .
, D
.
:
void fun(T. )(T args) {
gun(args);

}
void gun(T)(T value) {
w r i t el n ( va l u e);

}
unittest {
fun(1);
/ /
fun(1, 2.2); / / ! gun
/ / !

>
, .
, , ( , args)
- , args
gun. ?
,
. gun(args),
,
.
gun(args), gun(args[0],
args[1]........ args[S - 1]).
gun(args[0], args[1]), gun
, - .
,
fun args.
void f un ( T. . . )(T args) {
w r i t e l n ( t y p e o f ( a r g s ) . s t ri n g o f ) ;

>
typeof - ;
args,
. .stringof, ,
,
. :
(int)
(int,

double)

208

. .

, ,
, .
:
(int, 1).
/ /
( i n t , double) value = (1, 4.2);

, : ,
,
.
. ,
( ,
: auto).

5.10.2.2. Tuple tuple



,
. (-!
),
, .

Tuple, - tuple.
std.typecons.
, , int double, :
Import std.typecons;
unlttest {
T up l e ! ( int , double) value = tuple(1, 4.2); / / !

}
, tuple(1, 4.2) Tuple!(in t, double),
:
auto value = tuple(1, 4. 2); / / "!"

Tuple! (int, double) , ,


,
,
.expand Tuple.
fun gun :
i m p o r t s t d . s t d i o , std.typecons;
void fun(T. )(T args) {
/ / , ""
gu n( t upl e (a rgs) ) ;

>
void gun(T)(T value) {

209

5.10.
/ /
writeln(value.expand);

>
void main() {
fun(1);
/ /
fun(1, 2.2); / /

>
, fun
(Tuple) gun,
, , . value.expand
, ,
Tuple.
Tuple ,
, .
Tuple ( )
.

5.10.3.
. 1
,
.
,
.
,
,

( ,
in lin e-). D
.

,
.
, .

5.10.3.1.

D .
printf. D:
extern(C) Int printf(in char* format,

);

1 ,

, . - . ..

210

5. .

. extern(C) .
, .

. (mang
ling) ,
.
, . ,
extern(C) ,
, in char* format -
, ,
(...).
, .
, ,
.
n0Anp0rpaMMa.HanpHMep,npHBbi30Beprintf(''%d + %d=%d', 2, 3, 5)nep 5, 3, 2 .
.
, stdarg,h.
D std.c.stdarg.
-, v a _ list,
. va_start
v a _ list
.
void v a_ st ar t ( T )( out v a _ l i s t , ref T parmn );

- v a _ list, ,
, .
.

, va_start . 1()11 foo(...); .
va_arg
. -
,
. ,
.
T va_arg(T)( r ef v a _ l i s t );

va_copy va_
l i s t . v a _ list - ,
.
, .
void va_copy( out v a _ l i s t dest, v a _ l i s t sr c );

5.10.

211

va_end
. va_start va_copy
va_end.
void va_end( v a _ l i s t );

stdarg ,

.
, v a _ list - .
.

. ,
.
:
import s t d . . s t d a r g , std.conv;
extern(C) s t r in g cToStr ing( str ing type,
.) {
va_list args_list;
v a _ s t a r t ( a r g s _ l i s t , type);
scope(exit) va_end( ar gs_list );
switch (type) {
case "i nt":
auto i nt_val = v a _ a r g ! i n t ( a r g s _ l i s t ) ;
return t o ! s t r i n g ( i n t _ v a l ) ;
case "double":
auto double_val = v a _a r g!doubl e (a rgs _l i st );
return t o! st r i ng( doubl e_va l ) ;
case "conplex":
auto re_val = va _a r g!doubl e (a rgs _l i st );
auto im_val = va _a r g!doubl e (a rgs _l i st );
return t o ! s t r i n g ( r e _ v a l ) ^ " + " ^ t o! s t r ing ( im_v a l) ^ "i";
case "s t ri ng":
return v a _ a r g ! s t r i n g ( a r g s _ l i s t ) ;
default:
as ser t( 0, " ");

}
}
unittest {
asser t ( cToSt ri ng(" i nt ' ' 5) == "5");
assert(cToString("double" 2.0) == "2");
as ser t( cT o S t r i ng( " st r ing" "Test s t r i n g " ) == ''Test s t r i n g " ) ;
assert(cToString("complex" 3.5, 2.7) == "3.5 + 2. 7i ") ;

}

, ,
.
, .

212

5. .

:
. , :
cToString("s tr i ng "

3.5, 2.7);

. , , scanf
,
,

- , .
D
.

5.10.3.2.
D
D
:
void f o o ( .

);

, ,
D ( extern(D)),
.
, .
: _arguments TypeInfo[]
_argptr v a _ list. _argptr
, _arguments
.
.
.
- TypeInfo .
T typeid(T).
.
typeid(int) is typeid(int) .
TypeInfo
object. object, object.di,
,
-
. :
import s t d . c . s t d a r g , std.conv;
s t r i n g d T o S t r i ng (s t ring type, .. ) {
va_list args_list;
va_copy(args_list , _ar gptr ) ;
scope(exit) va_e nd( ar gs_l i st );
switch (type) {
case "i nt ":
asser t( _ar gument s.l ength == 1 && _arguments[0] i s t yp ei d( i n t ),
" i n t . " ) ;

5.10.

213

auto int _va l = v a _ a r g ! i n t ( a r g s _ l i s t ) ;


return t o ! s t r i n g ( i n t _ v a l ) ;
case ' double":
assert(_argument s.l ength == 1 &&_arguments[0] i s typeid(double),
" double.");
auto double_val = v a _a r g!doubl e (a rgs _l i st );
return t o! st r in g( dou bl e_ va l ) ;
case "complex :
assert(_argument s.l ength == 2 &&
_arguments[0] i s typeid(double) &&
_arguments[1] i s typeid(double),
" complex ''
" double.");
auto re_val = va_ar g!dou bl e ( a r gs _l i st );
auto im_val = va_ar g!doubl e(args _l i st );
return t o ! s t r i n g ( r e _ v a l ) ^ " + " ' t o! s t r ing ( im_va l) ' "i";
case "s t ri ng":
assert(_argument s.l ength == 1 &&_arguments[0] i s t y p e i d ( s t r i n g ) ,
" s t r i n g . " ) ;
r eturn v a _ a r g ! s t r i n g ( a r g s _ l i s t ) . i d u p ;
default:
a s se r t ( 0 );

I
unlttest {
a s ser t ( dToSt r i ng( "i nt " 5) == ''5");
assert(dToString("double" 2.0) == "2");
asser t( dToSt r in g( "st ri n g" "Test s t r i n g ' ) == ''Test s t r i n g " ) ;
assert(dToString("complex" 3.5, 2.7) == "3.5 + 2. 7 i ") ;

>
.
, , va_arg,
-
. ,
Variant
std.variant:
import s t d . s t d i o , s t d . v a r i a n t ;
void pseudoVariadic(Variant[] var s) {
foreach (var; vars)
i f ( var .type == t y p e i d ( s t r i n g ) )
writeln("CTpOKa:

''

v a r .g e t!str in g );

else
i f ( v a r . t y p e == t y p e i d ( i n t ) )
^1(" :

"

v a r .g e t!in t);

else
writeln("He3HaK0MHfi :

"

v a r.ty p e);

214

5. .
void templatedVariadic(T. .)(T args) {
pseudoVariadic(variantArray(args));

}
void main() {
templatedVariadic("3flpaBCTByii, !"

42);

}
templatedVariadic, ,
in lin e -,
.

5.11.
D - ,
,
.
, ,
, :
, .

5.11.1.
- ,
, . D ,
, ,
.
,
. V2?
1,4142; , . ,
y[2 ,
, , , ,
,
. .
- ,
, , . (, ,
. , ,
.)
, .
: , ,
.
, -
. ,
- -
.

5.11.

215

,
, , ,
.
, 1
.
,
, .
,
.
,
, .
,
pure:
pure bool leapYear(ulnt ) {
return ( % 4) == 0 && ( % 100 | | ( % 400) == 0);

}
,
pure bool leapYear(uint );

, leapYear
. , , leapYear(2020) .
,
, leapYear. :
pure bool leapYear(uint ) {
auto r es u l t = ( % 4) == 0 && ( % 100 | | ( % 400) == 0);
i f ( r e s u l t ) wri tel n(y, " - !"); / / !
/ / !
return result;

}
writeln .
, .
,
. leapYear .
,
, daysInYear:
/ /
pure uint daysInYear(uint ) {
return 365 + leapYear(y);

}
1 ,
,
. - . ..

216

5. .

5.11.1.1. ,

, . D
,
. ,
, .
, .
:
ulong fib(uint n) {
return n < 2 ? n : fib(n
}

1) + fib(n

2);


.
, fib ,
, , -
, ,
. , ?
fib(10) fib(20)
, fib(50) 19 . ,
fib(1000) (
, V2.)
,
?
ulong fib(uint n) {
ulong iter(ulnt i, ulong fib_1, ulong fib_2) {
return i == n
? fib_2
: ite r (i + 1, fib_1 + fib_2, fib_1);
}
return iter(0, 1, 0);
}
fib(50) .
()1 ,
(. 1.4.2)
. ( ,
0 (lo g )).
, fib
. -
, ,
, -
iter:
* - ,
. - ..

5.11.

217

ulong fib(u int n) {


ulong fib_1 = 1, fib_2 = 0;
foreach (i; 0
n) {
auto t = fib_1;
fib_1 += fib_2;
fib_2 = t;

}
return fib_2;

)
, .
, .
.
, , fib
. , ,
fib
, , . ,
,
, . ,
:
(
) ( ,
), .
D :
,
.
pure, :
ulong fib(u int n) {
/ /

}
D ,
, , :

( ).

5.11.2. nothrow
nothrow ,
. pure, nothrow
. :
import std.stdio;
nothrow void tryLog(string msg) {
try {
stderr.writeln(msg);

218

5. .

} catch
//

(E xcep tion ) {

}
}
tryLog ,
. , .
tryLog
.
-
. ,
, ,
, nothrow
.
nothrow ,
.
: 1)
(
,
), 2) try,
. :
nothrow void

s e n s i t i v e ( W i d g e t w) {
tryLog("Ha4HHaeM '');

try {
w.m ayT hrow();

//

tryLog("O nacH an '');


} ca tch (E xcep tion ) {
tryLog("OnacHaR " );

}
}
tryLog try,
, .
catch
try.
pure nothrow? ,
,
.
, ( exp,
sin, cos), - pure, nothrow.

5.12.
, ,
( ),
D. ,
, .

5.12.

219

, , .
,
. ,
[35, 3.2.1, . 1 0 -2 6 ].
: m > 0,
0 < < . 1 0 < < .
0 < < m ,

:
x n+1 = ( + ) mod m
:
, m , , ,
getNext * n+1.
. , .
. , = 1 = 1
0, 1, ..., m 1, 0, ..., m 1, 0, 1, ...,
.

, : .
- 0
m - 1, m
, (
,
: ).
,
, . uint
m = 232 (
), = 210, = 123, 0 -
, 1 7 8 0 5 8 8 6 6 1 . :

im port s td .s t d io ;
void m ain () {

enum u in t = 210, = 123, x0 = 1_780_588_661;


au to x = x0;
fo rea c h ( i ; 0
100) {
x = * x + ;
w rite ln ( x ) ;
}
}

:

1 ,
, > 0.

220

5. .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

261464181
3367870581
2878185589
3123552373
3110969461
468557941
3907887221
317562997
2263720053
2934808693
2129502325
518889589
1592631413
3740115061
3740115061
3740115061

17

. ,
,
. 14- :
,
, 3 7 4 0115061 ( )
(3740115061 * 210 + 123) mod 232. ,
!
, m , ,

.

m ( ):
1. m .
2. - 1 .
3. - 1 4 , m 4.
m
1.
1:
/ /
ulong gcd(ulong , ulong b) {
while (b) {
auto t = b;
b = b;
= t;

}
return ;
>
1

,
(...) .

5.12.

221

,
. ,
% -
(, ).
.
factorize,
, , factorize -
, . ,
, primeFactorsOnly(n),
n, .
( - 1) % primeFactorsOnly(m) == 0. , primeFactorsOnly.
.
: p v 2, 3, ...,
, n , ,
- .
n, .
- n, .
(, ,
. : .
.)
,
. n mod k
k, ( 2):
2, 3, 5, 7, 9, ... , n k,
k, n * k: n
n / k, n k. , k
n ,
k. ,
,
, .
:
ulong primeFactorsOnly(ulong n) {
ulong accum = 1 ;
ulong iter = 2;
for (; n >= iter * iter; iter += 2 - (iter == 2)) (
i f (n %iter) continue;
accum *= iter;
do n /= iter; while (n %iter == 0);
}
return accum > n;
}
iter += 2 - (iter == 2), iter,
2, , iter 2:
3. , iter

222

5. .

2, 3, 5, 7, 9 . .
, 4, 2
n.
n >=
iter * iter, n >= iter? . iter
Vn" n, ,
n iter: ,
k, , n == k * iter,
iter , k
iter, , k * iter - n,
.
primeFactorsOnly:

u n itte s t {
assert(pri meFactors0nly(100) == 10);
asser t( pri meFactor s0nly( 11) == 11);
assert(primeFactorsOnly(7 * 7 11 * 11 * 15) == 7 * 11 * 15);
assert(primeFactorsOnly(129 * 2) == 129 * 2);

}
-,

:
bool properLinearCongruentialParameters(ulong m, ulong , ulong ) {
/ /
i f (m == 0 11 == 0 11 >= m 11 == 0 11 >= rn) re tu rn fa ls e ;
/ / m
i f (gcd(c, m) != 1) re tu r n f a ls e ;
/ / - 1 m
i f ( ( a - 1) %primeFactorsOnly(m)) re tu rn f a ls e ;
/ / - 1 4, m 4

if

( ( a - 1) % 4 == 0 &4 m % 4) re tu rn f a ls e ;

/ /

r e tu rn tr u e ;
}
m, :

u n itte s t {
/ /
a s s e r t ( ! properLinearCongruentialParameters(
1UL 32, 210, 123));
/ / "Numerical Recipes" [48]
assert(properLinearCongruentialParameters(
1UL 32, 1664525, 1013904223));
/ / Borland /++
assert(properLinearCongruentialParameters(
1UL 32, 22695477, 1));
/ / g li bc
assert(properLinearCongruentialParameters(

5.12.

223

1UL 32, 1103515245, 12345));


/ / ANSI
assert(properLinearCongruentialParameters(
1UL 32, 134775813, 1));
/ / Microsoft Visual /++
assert(properLinearCongruentialParameters(
1UL 32, 214013, 2531011));

}
, properLinearCongruentialParameters ,

. ,
.
? ?1
, ?
s ta tic if?
?
, ,
. m, n
, properLinearCongruentialParameters
, ,
. D ,
D -
, , ,
.
,
. :

u n itte s t {
enum ulong m = 1UL 32, = 1664525, = 1013904223;
/ / 1: s t a t i c a s s e r t
s t a t i c assert(properLinearCongruentialParameters(m, , c));
/ / 2: ,
/ / enum
enum proper1 = properLinearCongruentialParameters(m, , );
/ / 3;
s t a t i c proper2 = properLinearCongruentialParameters(m, , );

)
,
, ,
properLinearCongruentialParameters -
,
. :

s t r u c t LinearCongruentialEngine(UIntType,
UIntType , UIntType , UIntType m) {

, - . - . .

224

5. .

s t a t i c assert(properLinearCongruentialParameters(m, , ),
" LinearCongruentialEngine");

}
, ,
std. random.
(
, ),
. -,
, properLinearCongruentialParameters LinearCongruentialEngine. , ,
, ,
.
LinearCongruentialEngine :
. -,
, ,
, m, .

,
.
: -
, .
,

++. , (
) .

1. ,
( ). ,
,
(union) (cast), .
, ,
. ,
,
D. ,
- ,
, .

. - . . .

6
.
-

- ()
,

. ,
- .
, ,

.
:
,

. D ,

. -
D .
- -
- [40] (

[46, 18]).

6.1.
D .
,
. , ,
. :

226

6. . -
c l a s s Widget {
/ /
enum fudgeFactor = 0.2;
/ /
static immutable defaultName = 'A Widget";
/ / , Widget
s t r i n g name = defaultName;
ulnt width, height;
/ /
static double howFudgy() {
return fudgeFactor;

}
/ /
void changeName(string another) {
name = another;

>
/ / ,
final void quadrupleSize() <
width *= 2;
height *= 2;

}
}
Widget new,
: new Widget (.
2.3.6.1). ,
Widget, ,
, .
, , ,
. :
unittest {
/ / Widget
assert(Widget.howFudgy() == 0.2);
/ / Widget
auto w = new Widget;
/ / Widget
assert(w.name == w.defaultName); / / Widget.defaultName
w.changeName('Mo ");
assert(w.name == ' ');

}
.
w.defaultName, Widget.defaultName.

. ,

( ).
w : .

6.2. -

227

6.2. -
:
import s t d . s t d i o ;
c l as s {
i n t x = 42;

>
unittest {
auto a1 = new ;
a s s er t ( a 1 . x == 42);
auto a2 = a1;
a2.x = 100;
a s se r t ( a1 . x == 100);

}
( ),
, a1 a2 : a2
a1.
- , , a2 a1. auto a2 = a1; ,
(. 6.1).

. 6.1. auto a2 = a1

:
,
.
(, ), ,
; -
(. 7).
, (
), . ,
, (bindings); ,
, , a1 a2
, , .

228

6. . -

.
, ( ,
). - ,
. , ,
:
unittest {
auto a1 = new ;
auto a2 = new ;
a 1. x = 100;
a2.x = 200;
/ / a1 a2
auto t = a1;
a1 = a2;
a2 = t;
a s s e r t ( a 1 . x == 200);
a s s e r t ( a 2 . x == 100);

}

swap std.algorithm: swap(a1, a2),
. . 6.2
.
,
. ,
: , ,
. (
, .)
( a1 a2)
, .
, -
,
( ).1
1 D
(manual memory management)
delete: delete obj;,
obj null (. ), ,
, . obj null,
. :

(
, ),
. -
del et e ,
.
. : ,
, del ete obj obj , ,
del et e . - . ..

229

6.2. -

0
-

x=100

x=100

x=200

x=200

. 6.2. .
;
(, i n t ) ,
:
,
.
, - , -
(null). . i n i t
n u l l .
n u l l n u l l .
:
unittest {
;

assert(a l s nul l ) ;
= new ;
a s s e r t ( a ! l s null) ;
= null;
a s s e r t ( a l s null);
= .i n i t ;
a s s e r t ( a l s null);

}
(, n u l l )
, (

).
,
,
.
;
a.x = 5; / / ! !

,
: (
),
. :
;

if ( ') {
= new ;
}

230

6. . -

i f (<) {
a. x = 43; / /

}
, ,
<> .
,
, , ,
( , ,
).
D
,
.
,
, :
+ . ,
,
. ,
,
(
, ).
,
,
-
. , .
++, , ,

,
, .
+ .
, ,
. ,
, (
) .
, , * ,
,

. ,
, ( auto a2 = a1
, a1, a2
). , , ,
-
( , ).
.
, , pa-

6.3.

231

, .
, .
, .

.
- . a1 a2 . 6.1
, . .
,
. , ,
: , .
, ,
, (
).

,
clone. :
,
,
.
- int.
,
:
, . (
,
, .)
- .
, .

, (
- ,
). D
.
:
, class;
struct ,
.

6.3.
,
, .
new:
import std.math;
class Test {

232

6. . -

double = 0.4;
double b;
}
unittest {
/ / new
auto t = new Test;
assert(t.a == 0.4 && isNaN(t.b));

}
new Test Test
, Test,
.
T ,
T.init ( .in it
. 2.1).
,
.in it,
,
.
,
0.4, b , ,
double.init, N aN ().

6.3.1.
,
.
. th is
.
class Test {
double = 0.4;
int b;
th ls(in t b) {
th is . b = b;
}
}
unittest {
auto t = new Test(5);
}
,
. Test, ,

auto t = new Test;


. -
:

6.3.

233

, .
D :
, :
cl as s Test {
double = 0.4;
i n t b;
t h i s ( i n t b) {
t h i s . b = b;

}
t h i s ( ) {} / / no ,
/ /

}
( , . 6.5) th is
- . (
,
) :

, , ,

th is,
.
th is .fie ld
field , th is,
-:
c l ass NoGo {
void f un( ) {
/ / t h i s
t h i s = new NoGo; / / ! this!

}
>
( 5.5)
: ,
(
, ).

6.3.2.
Widget, :
cl as s Widget {
t h i s ( u i n t height) {
t hi s .wi dt h = 1;
t h i s . height = height;

>
t h i s ( u i n t width, u int height) {
t hi s .wi dt h = width;
t h i s . height = height;

234

6. . -

}
u in t width, height;

}
,
, , ,
:
c l a s s Widget <
t h i s ( u i n t h ei ght ) {
t h i s ( 1 , height); / /

}
t h i s ( u i n t width, u in t height) {
t h i s . w id t h = width;
t h i s . h e i g h t = height;

}
u in t width, height;

>
- this(1, h)
. -,
. -, ,
, ,
. , :
t h i s ( u i n t h) {
i f (h > 1) {
t h i s ( 1, h);

>
/ / !

}
, ,
, .
:
,
. ,
, (
), .
:
t h i s ( u i n t h) {
i f (h > 1) {
t h i s ( 1, h);

}
t h i s ( 0 , h);

}
,
, .

6.3.

235

,
, .
.

6.3.3.
- .
,

. .
D :
1. .
,
. ,
, - ++, D
1.
, :
.
.
. ,
,
= ,
. i n i t .
2. .

T ( ) ,
.
3. . ,
.
, .

,
,
.
, (,
).
,

. ,

1 D
( scope)
( ).
,
, . . ..

236

6. . -

, ,
,
(dead assignm ent elimination).
,
void;

: 1.
, = void
.
,
. ., 0.1, 0.2, ..., 12.7.

c la s s Transmogrifier {
d o u b le[1 2 8 ] a lp h a = void;
th is () {
fo re a c h ( i , r e f e; alpha) {
e = i * 0.1;

}
>

. , Transmogrifier
alpha usedAlpha,
. ,
, ,
0 usedAlpha - 1:

c l a s s Transmogrifier {
d o u b le [l2 8 ] alpha = void;
s i z e_ t usedAlpha;

th is () {
/ / usedAlpha 0,
/ / alpha -

}
}
usedAlpha ,
Transmogrifier. usedAlpha
alpha[usedAlpha .. $],
. , ,
( ,
).

void
,
. i n i t . - . ..

6.3.

237

,
,
.

6.3.4.
D ,
. ,
(
). ,
, ,
.
, .
,

. ,
^this:
import c o r e . s t d c . s t d l i b ;
cl as s Buffer {
pr i vat e void* data;
/ /
this() {
data = malloc(1024);

}
/ /
'this() {
f ree( dat a);

>
}
- ,
.

,
.

6.3.5.
, ,
:
1. ( 3 )
.
: ,
.
,
, , ,

238

6. . -

,
.
2. .
3. ;
.
4. ( ) ,
, .
5. ( - ) .
, :
,
, .
, ,
. D
-
.
,
(, ).

. -, ,
4,
.
D , -
, ,
.
, clear
object ( ,
).
unittest {
auto b = new Buffer;
cl e a r( b) ; / / b
/ / b

}
clear(b)
b ( ),
Buffer.init
null,
. ,
++, clear
, D delete. ( D delete,
.)
, GC.free() core.memory,

6.3.

239

, , .
, clear ,

. clear(obj); ,
, obj
, .
, D :
unittest {
auto b = new Buffer;
auto = b; / / b
cl ear( b);
a s s e r t ( b1 .d a t a ! i s nul l ) ; / /
/ / () "" b1

}
, clear
, ,
,
. ,
.
, , ,
, .
? :

,
( , ,
),
. new clear
. ( ,
malloc free GC.free.)
()
().
,
. ,
, .

6.3.6. 2
,
,
. , -

1 . . ..

,
,
. - . ..

240

6. . -

- .
.
,

. ,
.
.
-
, ,
.
- ,
.

. , ,
core.memory.GC.collect().
core.memory.GC.disable()
, core.memory.GC.enable() .
disable , enable

.
core.memory.GC.minimize()
.
,
,
.
:

im port s t d . c . s t d l i b ;
c la s s Storage
<

p r iv a te SomeClass sub_obj_1;
p r iv a te SomeClass sub_obj_2;
p r iv a te void* data;
th is ()
{
sub_obj_1 = new SomeClass;
sub_obj_2 = new SomeClass;
data = malloc(4096);

^ th is ()
{
f re e ( d a ta ) ;
/ / data malloc ,
/ / , .

>
}

6.3.

241

Storage obj = new Storage; / / Storage

delete obj; / /
obj .
obj? ,
. , , obj
, obj.
, :
~this()
{
delete sub_obj_1;
delete sub_obj_2;
f re e(d ata );

}
.
obj , ?
, obj
sub_obj_1. ,
obj ,
.
,
, ,
.
, ?
(. 6.15) (, ,
).
class Foo
{
char[] arr;
void- buffer;
th ls ()
{
a r r = new char[500];
buffer = std.c.m alloc(500);

}
^thls()
{
std .c.fre e(b u ffer);

}
private void dispose()
delete arr;

242

6. . -

d e le te ( v o id - v)
<

( c a s t( F ) v ) .d is p o s e ( ) ;
c o re.m em o ry .G C .free(v );

}
}
delete,
,
dispose.
dispose .

6.3.7.
, D, (
sta tic )
, .
,
s ta tic th is ().
,

.

:

c la s s (
s t a t i c a1;
s ta tic th is () {
a1 = new ;

s ta tic th is () {
a2 = new ;

s t a t i c a2;
}
.
main (
- ) runtim e
, .
a1 , a2.

.
, ,
. , :
,

6.3.

243

, ,
.
: ,
MA, - MB.
:

MA MB (MB MA
) -
( ,
);

MA MB
;

MB MA-
;

MA MB MB MA-
,
.

,
.
11.

, .
,
, ,
, :

c la s s {
s t a t i c a1;
s ta tic ^ th ls () {
clea r(a1 );

s t a t i c a2;
s ta tic ^ th is () {
clea r(a2 );

>
>
.
,
. a2
a1 .
, ,
, ,

244

6. . -

. 1
.

6.4.
.
, .
. (
.)
,
, .
. ,
,
.
,
Contact.
,
:
c l a s s Contact {
s t r i n g bgColor() {
return "";

>
}
u n ittest {
auto = new Contact;
a s se r t( c .b g C o lo r () == "");

}
, ,
. , -
,
:
c l a s s Friend : Contact {
s t r i n g currentBgColor = "-";
s t r i n g currentReminder;
override s t r i n g bgColor() {
retu rn currentBgColor;

}
s t r i n g reminder() {
retu rn currentReminder;

>
}

1 :
, , -
, - , . - . .

6.4.

245

: Contact ( Con
tact), Friend , Contact,
( currentBgColor currentReminder ) ( reminder ).
, Friend - Contact,
Contact - Friend.

Friend , Contact:
unittest {
Friend f = new Friend;
Contact = f; / / Friend
/ / Contact
auto color = c.bgColor(); / / Friend

}
Contact
Friend ,
, ( ) Friend.
, ,
-
. ,
override ( Friend bgColor),
, c.bgColor() (
Contact, Friend)
, Friend.
, ,
.

6.4.1.

, .
, ,
.
.
D , D
, , .
, )
D.
X , X
X .
, X,
X ,
.

246

6. . -


/ / ,
,
/ .
, - , -
, ( - , ).
- : S T,
S -
, . :
. ,

; ( D).

:
. , , - ^>roper
subtype).

6.4.2. - .

.
, -
:
c la ss C o n ta c t {
}
c la ss F rien d : C o n ta c t {
}
void f u n ( C o n t a c t ) {
}
u n itte st {
a u t o = new C o n t a c t ; / / C o n t a c t

fun(c);
a u t o f = new F r i e n d ;

/ / f F r ie n d

fun(f);

>
fun Contact,
f ,
Friend (, , ) Contact.
,
. :
c l a s s C o n t a c t { s t r i n g b g C o l o r ( ) { r e t u r n ""; } }
c la ss F rien d : C o n ta c t {
o v e rrid e s t r i n g b g C o l o r ( ) { re tu rn " - " ;

}
u n itte st {

C o n t a c t c = new F r i e n d ; / / C o n t a c t ,
/ / F rien d
a s s e r t ( c . b g C o l o r ( ) == " - " ) ;

247

6.4.
/ / !

}
, Contact,
, Contact, -
Friend. ,
. reminder, Friend
Contact. a s s e r t
, : c.bgColor ,
Friend. 6 .3 ,
,
Friend, new,
. ,
, , , ,
Contact, Friend. ,
Contact Friend.
(null) .
Friend Contact, , - . :
.
Friend?
, .
cast:
u n ittest (
auto = new Contact; / /
//
auto f = ca st(F rie n d ) ;
a s s e r t ( f i s n u ll) ;
//
//
= new Friend;
//
f = ca st(F rie n d ) ;
//
a s s e r t ( f ! i s n u ll) ;
//


. Contact
f Friend

: Contact, : Friend
: Friend, : Friend
!

6.4.3. -
o v e r r i d e -
Friend. bgColor. .
, ,
. override?
.
,
. , ,
. ,
- ,
-. , , Contact
bgColor. Friend

248

6. . -

bgColor,
. Friend
, Friend.reminder,
. - (
) reminder Contact
, : ,
Contact.reminder, Friend.re
minder , , Contact
Friend, - Friend .
, , . ,

Contact.
Contact ,
. ,
,
.
, override
- -.

6.4.4.
, ,
. , , Button,
Clickable. Clickable ,
- ,
- .
, Button onClick,
Clickable, ,
, Clickable.onClick, , .
class Clickable {
void o n C l i c k ( ) { . . }
>
class Button : C l i c k a b l e {
void draw C lic k e d () {
override void o n C li c k ( )

}
{
draw C lic k e d ();
/ /
s u p e r . o n C l i c k ( ) ; / /

}
}
, ,
super,
.
- ,
(, Button.onClick
super.onDoubleClick). , ,

6.4.

249

, .
.
:
class Base {
double number = 5.5;
)
class Derived : Base {
Int number = 10;
double fun() {
return number + super.number;
}
}
Derived.fun ,
,
.
.,
, .
, super - , ,
-.
, : Base.number super.number.
, super ,
: ,
.
,
.
super
,
, .
,
, .
(. 6.3.4) -
, .
,
( ,
clear(obj)) D
.

6.4.5.
Widget, TextWidget VisibleWidget.
, ,
Widget.
Widget, Widget,
- TextWidget,
TextWidget . .

250

6. . -

duplicate ,
- :
c l a s s Widget {
this(W idget source) {
/ /

}
Widget d u p lic a te ( ) {
retu rn new W idget(this); / /
/ / this(W idget)

}
}
.
TextWidget:
c l a s s TextWidget : Widget {
this(TextW idget source) {
super(source);
/ /

}
override Widget d u p lic a te ( ) {
return new TextWidget(this);

}
}
, : TextWidget.duplicate Widget,
TextWidget.
TextWidget.duplicate, , TextWidget.
, TextWidget.duplicate
,
Widget - , Widget.duplicate.
( ):
void workWith(TextWidget tw) {
TextWidget clone = tw .d u p lic a te () ; / / !
/ / Widget
/ / TextWidget!

}

, D ,
. ,
:
,
, .
TextWidget.duplicate TextWidget.
, ,

6.5.

251

. (
. , .)

6.5.


, , ( !) .
- ,
.
,
sta tic:
class Widget {
static Color defaultBgColor;
static Color combineBackgrounds(Widget bottom, Widget top) {
}
}
th is.
, -
, . ,
defaultBgColor combineBackgrounds - :
unittest {
auto w1 = new Widget, w2 = new Widget;
auto = Widget.defaultBgColor;
/ / : w1.defaultBgColor;
= Widget.combineBackgrounds(w1, w2);
/ / : w2.combineBackgrounds(w1, w2);

}

, . :
,
.
/ / Widget
auto = (new Widget).defaultBgColor;

6.6.


. ,
, .

252

6. . -

. (
[27].) -
, fin al.
-,
.
:
c l a s s StockTicker {
f i n a l void updatePrice(double l a s t ) {
d o U p dateP rice(last);
re fre sh D isp la y ();

>
void doUpdatePrice(double l a s t ) { ..
void refreshD isplay () { .. }

}
doUpdatePrice refreshDisplay , ,
StockTicker. ,
,
,
. updatePrice ,
,
. ,
, updatePrice :
f i n a l void updatePrice(double l a s t ) {
s c o p e(ex it) refreshD isplay();
d o U pd ate P ric e(la st);

}
scope(exit)
, doUpdatePrice
. ,
.
,
.
, ,

, ,
override. ,
. ,
-,
; - ,
. (
),
, 100% ,
. , ,
; ,
,

6.6.

253

, .
,
, .
-, ,
, , .
, - ,

, .
,
, ,
,
. -,
,
,
. ,
, ,
,
, .
Java C #,
f i n a l , D
, . ++,
: ++
(
- , )
, v i r t u a l .
:
, . ,

-
.

6.6.1.
, .
f i n a l :
c l a s s Widget {
}
f in a l c l a s s UltimateWidget : Widget {
>
c l a s s PostUltimateWidget : UltimateWidget {
} / / !
/ /


.
. ,
: .
-
. , ,

254

6. . -

,
,
.

6.7.
-,
- .
,
.

. ,
, ,
:
.
-
(inform ation hiding),
. ,

,
. ,
(data hiding).
-
,
,
.
, ,
-
. .
, - .
?
. 1960- ,
-1,
( )
. ,
O S/360,

, [13,
7]. , ,
;
, ,
.

. - . - - , 2 0 0 0 .

6.7.

255


[44]. 1995 , -,
. 1972
,
: , , ,
. ,
,
: ,
[32, . 138].
D. , ,

.
.

6.7.1. private
private ,
( ) (.
7). private ().
:

. , private
, D
:
( ).
,
,
. ,
.

6.7.2. package
package ,
( ) (. 7).
package :
, ,
,
.
.

6.7.3. protected
protected ,
.
,

256

6. . -

, ,
,
. :
class {
/ / x
p r iv a te i n t x;
/ /
/ / setX()
protected void setX (in t x) { t h i s . x = x; }
/ / getX()
public i n t getX() { return x; }

}
, ,
protected, :
, ,
, protected.
protected
.

6.7.4. public
public ,

. ,
, -
( , ,
).
D public - ,
.
,
, ,
() private,
.
, ,
.

6.7.5. export
, public -
, . D
, : export. ,
export,
, .
, .
,
,
. D

6.7.

257

, export
.

6.7.6. ?
: D
? , ,
- , ,
private , protected,
. , protected , public ( - public
, export ).
, protected package. ,
,
, , ,
. protected - private public?
? ?
-, 1999 ,
2000 , ,
, .
[41],
:
, ?
, .

.
: private - , public - , protected
. ,
, protected,
, - .
,
, - , ,
. (: ) ,
?
? - -?
.
private.
.
,
; ( , 10000 )
. ,
,
,
,
. , private
:
, .

258

6. . -

package
. ,
, ,
(, ,
).
: ,
private-. ,
, ,


.
, protected
, . -, protected
, private package:
, ,
, ,
.
fin al
. ,
, .
, ,
, ,
. (,
.)
, : -
private package, .
protected .

? ,
. -
, . , ,
,
, , ,
.
public
, ,
. ,
. , export
:
, ,
,
, , - ,
, .

259

6.7.

. 6.3

. , ,
,
.
, ,
,
, .
.
, protected
private public, public,
( ).

1 2 - -

101 -

I
I

I
I

I
I

I
I

I
I

1 0 ----------------- !----------------- !------------------ !----------------- !------------------ 1


private

package

protected

p u b lic

e x p o rt

. 6.3. ,

. ,
.
, , protected,
public export, ,

260

6. . -

6.8.
D, ,
. Object.
, :
class {

}
:
c l a s s : Object {

}
Object
- , .
object.di object.d,
, . ,
D,
, .

. , Object
.
Object:
c l a s s Object {
s t r i n g t o S tr in g ( ) ;
s iz e _ t toHash();
bool opEquals(Object rhs);
int opCmp(Object rhs);
s t a t i c Object f a c to r y ( s tr in g classname);

}

.

6.8.1. string toString()


.
toString :
/ / t e s t . d
c l a s s Widget {}
u n ittest {
a s s e r t( ( n e w W id g e t) .to S tr in g ( ) == "test.W idget");

}
: ,
.
, ,
module (. 11.8).

6.8.

261

6.8.2. size_t toHash()


(
32 32- 64 64-). -
. ,
. ,
-, - : toHash
,
, , ,
, . , -
. -
() .
.

6.8.3. bool opEquals(Object rhs)


true, th is , rhs1
. .
equals Java ,
, . D
.
, :
a1 is a2 (. 2.3.4.3),
a1 a2, , a1 a2
(. . 6.1).
, , .
, ,
. D
== !=. .
, <lhs> <rhs> : <lhs> == <rhs>.
,
object.opEquals(<Jfis>, <rhs>).
<lhs> != <rhs> !object.opEquals(<Jfis\ <rhs>).
, , object - ,
D
import .
,
object.

, object.opEquals(>ifis\ <rhs>) ,
. -, (null)
1

rhs ( right hand side - ) - ,


. lhs ( left hand side - ) -
, . - . .

262

6. . -

true. , x, , z
:
/ / null ; null
as s e rt(x != n u l l ) ;

/ /
as s e rt(x == x);

/ /
a s s e r t ( ( x == ) == ( == x ));
/ /
i f (x == && == z) as sert(x == z);
/ / toHash
i f (x == ) a s s e rt(x .to H a sh () == y.toH ash());

opEquals - :

,
opEquals , ,
.
object.opEquals
,
opEquals, ,
. object.opEquals:
/ / o b je ct.d
bool opEquals(Object lhs, Object rhs) {
/ /
/ / ,
i f ( lh s l s rhs) return true;
/ / n u ll,
i f ( lh s i s n u l l | | rhs i s n u l l ) return false;
/ / , opEquals
i f ( ty p e i d ( lh s ) == ty p e id ( rh s ) ) return lhs.opE quals(rhs);
/ / - opEquals
return lhs.o pE quals(rh s) && rhs.opEquals(lhs);

)
-,
, , , - true (
). , ,
, null, fa lse (
null).
, ; ,
lhs.
opEquals(rhs). :
. ?
,
opEquals: true, th is , rhs
. th is,
, rhs.

6.8.

263

-
: ,
? ,
- , -
, .
(Joshua Bloch) E ffective Java [9],
(Tal Cohen) [17].
.
.
, :
c la s s Rectangle {
}
c la s s Window {
}
c la s s Widget {
p riv ate Window parent;
p riv a te Rectangle position;
.. / / Widget

>
TextWidget Widget,
- .
c lass TextWidget : Widget {
p riv ate s t r i n g te x t;

}
opEquals ?
Widget ,
:
/ / Widget
override bool opEquals(Object rhs) {
/ / Widget
auto th a t = cast(Widget) rhs;
i f ( ! t h a t ) return f a lse ;
/ /
return parent == t h a t.p a r e n t
&& po sition == t h a t .p o s itio n ;

>
cast(Widget) Widget rhs.
rhs - ,
rhs Widget Widget,
null.
TextWidget :
TextWidget
.
/ / TextWidget
override bool opEquals(Object rhs) {

264

6. . -
/ / TextWidget
auto t h a t = cast(TextWidget) rhs;
i f ( ! t h a t ) return f a lse ;
/ /
return sup er.op E q uals(that) && te x t == t h a t . t e x t ;

}
tw TextWidget w
Widget, .
w tw .
tw : ,
w TextWidget.
, w == tw , H o t w != ,== . ,
TextWidget: TextWidget.opEquals
, rhs Widget,
TextWidget,
Widget. :
/ / TextWidget.opEquals -
ov errid e bool opEquals(Object rhs) {
/ / Widget
auto t h a t = cast(Widget) rhs;
i f ( ! t h a t ) return fa lse ;
/ / Widget? ,
i f (!su p e r.o p E q u a ls (th a t)) return fa ls e ;
/ / TextWidget?
auto th a t2 = cast(TextWidget) rhs;
/ / ,
i f ( ! t h a t 2 ) return true;
/ / TextWidget
return te x t == t h a t 2 .t e x t ;

}
, TextWidget
. , *
: TextWidget tw1 tw2,
(- ),
w Widget.
, tw1 == w tw2 == w,
tw1 != tw2.
, :

. : object.opEquals(Object, Object) -
,
.

6.8.

265

6.8.4. int opCmp(Object rhs)


1,

. , th is
rhs; , th is rhs; 0,
th is rhs . opEquals,
opCmp .
: < b, <= b,
> b >= b.
, opEquals:
-
object.opCmp.
<, <=, > >= D <on> b
object.opCmp(a, b) <on> 0. < b
object.opCmp(a, b) < 0.
opCmp .
Object.opCmp .
, opCmp ,

x, z:
/ / 1.
assert(x.opCmp(x) == 0);
/ / 2.
i f (x.opCmp(y) < 0 && y.opCmp(z) < 0) assert(x.opCmp(z) < 0);
/ / 3.
i f ((x.opCmp(y) == 0 && y.opCmp(z) == 0) assert(x.opCmp(z) == 0);

,

. <,
, :
/ / 1. <
a s s e r t ( ! ( x < x));
/ / 2. <
i f (x < && < z) a s s e r t ( x < z);
/ / 3. !(x < ) && !( < x)
i f (!(x < ) && !( < x) && !( < z) && ! (z < y))
a s s e r t ( ! ( x < z) && !(z < x));

, <
. <
. , ,
;
1 , opCmp ,
. - . ..

266

6. . -

.
-
, opCmp.
, <,
, -
(x > - , < x, x <= - ,
!( > x), ..).
,
, , ,
, - : x < , !( < x).
, ,
x , x < < x
: ,
z x,
:
i f (x < && < x) a s s e r t( x < x);

, , ,
, assert,
. -
, .
:
opCmp opEquals:
/ / opEquals
i f (x == ) a s s e r t ( x <= && <= x);

opEquals :
, x <= <= x
, x
. , x == .
,
, - ,
.

6.8.5. static Object factory (string dassName)


,
. , ,
; factory
. factory .
/ / t e s t . d
import s t d . s t d i o ;
c l a s s MyClass {
s t r i n g s = ", !";

6.8.

267

void main() {
/ / Object
auto obj1 = O b je c t.fa c to ry (" o b je c t.O b je c t" );

assert(obj1);
/ / MyClass
auto obj2 = cast(MyClass) O b je c t.fa ctory("te st.M yC la ss'');
w rite ln (o b j2. s ); / / W r i t e s "Hello, w orld!
/ / factory null
auto obj3 = Object.factory("HecyuiecTByK^nPi");
assert( !obj 3 );

}

, [27,
23] . ,
void w id g etize () <
Widget w = new Widget;
. . / * w * / . . .

>
. , , ,
TextWidget, -,
, :
void widgetize() {
Widget w = new TextWidget;
./* w */.

}
, .
, ,
,
.
; ,
. ,
, ,
, ,
. -
/ [40]: (
, )
, . new
- , w,
.
,
widgetize :
void w id g etize (strin g widgetClass) {
Widget w = cast(Widget) O bject.factory(w idgetC lass);
/* w */.

268

6. . -

widgetize
,
Widget.
,
.
,
*Javas new considered harm ful ( new Java ) [4].

6.9.
( )
, . ,
(
),
.

. ,
. ,
Widget,
, -
- . ,
,
, ,
. .
D .
cla ss interface
.
,
.
. :
in t e r f a c e Transmogrifier {
void transm ogrify();
void untransmogrify();
f i n a l void thereAndBack() {
transm ogrify();
untransm ogrify();

>
}
, , Transmogrifier, . :
void aDayInLife(Transmogrifier device, s tr in g mood) {
i f (mood == "") {
d e v ic e .tra n s m o g rify ();
p l a y ( );
d e v ic e .untransm ogrify();

6.9.

269

} e ls e i f (mood == "") {
d e v ic e .thereAndBack();

)
}
,
Transmogrifier, aDayInLife
. :

c la s s CardboardBox : Transmogrifier {
o v e rrid e vo id transm ogrify() {
/ /
>

o v e rrid e void untransmogrify() {


/ /

}
}
,
. CardboardBox
:
aDayInLife(new CardboardBox, "");

,
.
, CardboardBox
Transmogrifier, aDayInLife.

6.9.1. (NVI)
- : Transmogrifier
. ,
?
!
2001 [52] ,
[55, 39].
, ( transmogrify
untransmogrify ), . -,
, ,
, . , ,
-.
,
: ,
, , ,
.
, ,
.

270

6. . -

, , ,
, .
,
. ,
, ,
.
, ,
, ,
,
, ,
,
. 1 (NVI)
. , Transmogrifier
,
thereAndBack,
.

, ,
(Non-Virtual Interface,
NVI). , NVI
,
,
, .
NVI ,
,
,
, NVI. Java
N V I, C # (
NV I ),
++ ,
,
.
D NVI, ,
. .
, Transmogrifier ,
:
transmogrify , untransmogrify ?
, thereAndBack,
transmogrify untransmogrify:
interface Transmogrifier {
/ /
final void thereAndBack() {
transm ogrify();

1 - ,
. - . . .

271

6.9.
untransmogrify();

>
/ /

p r iv a te :
void transm og rify();
void untransmogrify();
}
Transmogrifier .

: , Transomgrifier,
transmogrify untransmogrify,
. ,
Transmogrifier. -
thereAndBack, , ,
:
,
.
. ,
transmogrify untransmogrify:
class CardboardBox : Transmogrifier {

o v e rrid e p r iv a te v o id transm ogrify() <


o v e rrid e void untransmogrify() { .. }

} / /
/ / !
/ / untransmogrify
/ / !

}
, ,
, , :

c la s s CardboardBox : Transmogrifier {
o v e rrid e p r iv a te v o id transm ogrify() {
o v e rrid e p r iv a te v o id untransmogrify() {

} / /
/ /

doUntransmogrify();

void doUntransmogrify() {

/ /

}
CardboardBox doUntransmogrify, , untransmog
rify. , void untransmogrify()
.
,
.
, .
, D
NVI, - :
Transmogrifier ,
thereAndBack. :

272

6. . -
c l a s s Broken : Transmogrifier {
void thereAndBack() {
/ / ?
t h is .T r a n s m o g r if ie r . thereAndBack();
this.Transm ogrifier.thereA ndB ack();

}
/ / !
/ / Transmogrifier.thereAndBack

}
, , ,
Broken Transmogrifier,
obj.thereAndBack() obj
Broken; , thereAndBack
, Transmogri
fier. , obj.Transmogrifier.thereAndBack(), ,
, ,
, . ,
, .
: ,
.
,
. ,
. :
c l a s s Good : Transmogrifier {
void thereAndBack(uint times) {
/ / ?
foreach ( i ; 0
times) {
thereAndBack();

}
}
>
, :
obj.thereAndBack() - Transmogrify.
thereAndBack, obj.thereAndBack(n) Good.
thereAndBack. , Good.thereAndBack

.

6.9.2.
, ,
, . ,
super :

273

6.9.

im port std.exception;
c la s s CardboardBox : Transmogrifier {
p riv a te :
o v e rrid e v oid transm ogrify() {
}
o v e rrid e void untransmogrify() {
}
}

c la s s FlippableCardboardBox : CardboardBox {
p riv a te :
bool flip p e d ;
o v e rrid e vo id transm ogrify() {
e n fo rce (!flip p ed , " transmogrify:
" ");
super.transm ogrify(); / / !
/ / CardboardBox.transmogrify!

}
}
(flipped),
, -
. FlippableCardboardBox
enforce.
,
transmogrify . ?
,
doUntransmogrify,
,
. -
Transmogrifier,
private protected:

in te r f a c e Transmogrifier {
f i n a l void thereAndBack() {
p ro te c te d :
void transm ogrify();
v oid untransmogrify();

>

. ,
, . ,

. , Transmogrifier
transmogrify untransmogrify ,
:

c la s s BrokenInTwoWays : Transmogrifier {
p u b lic v oid transm ogrify() {
}
/ / !
p riv a te v oid untransmogrify() {
} / / !
}

274

6. . -

,
,
. ,
,

.

6.9.3.

, :
interface Timer {
final void run() {

}
interface Application {
final void run() {

>
class TimedApp : Timer, Application {
/ / run()

>
TimedApp
run(),
, , , .
fin a l (
Timer Application) ,
.
, : 1. run
Timer.run Application.run .
app TimedApp,
app.Timer.run() app.Application.run()
Timer Application . TimedApp
,
. , run().

6.10.
,
-
. ,
,
(, ).
: , ,
,
- abstract.

6.10.

275


-,
. - Shape.
, , ,
Shape (
). , Shape (
draw) ,
. ,
Shape.
c la s s Rectangle {
uint l e f t , rig h t, top, bottom;

>
c la ss Shape {
protected Rectangle _bounds;
a b s tra c t void draw();
bool overlaps(Shape th a t) {
return _ bounds.left <= th a t._ b o u n d s .r ig h t &&
_bounds.right >= t h a t._ b o u n d s .le f t &&
_bounds.top <= that._bounds.bottom &&
_bounds.bottom >= that._bounds.top;

}
}
draw , . -,
Shape draw. -,
Shape. -,

Shape, ( , ) draw.
,
; , Shape
RectangularShape, draw,
RectangularShape .
,
, . ,
Shape.draw.
, , : this.Shape.
draw().
, overlaps
.
,
. -

; ,
, .
, ,
. RectangularShape

276

6. . -

Shape
Shape, RectangularShape

. RectangularShape
. :
class Shape {
/ /

abstract void draw();


>
class RectangularShape : Shape {
/ / Shape
/ /
abstract void drawFrame();

}
class ARectangle : RectangularShape {
override void draw() {
}
/ / ARectangle

}
class SolidRectangle : ARectangle {
override void drawFrame() {
>
/ / SolidRectangle :
/ /

>
,
, !
,
,
- - - .
class A bstract {
abstract void fun();
}
class Concrete : A bstract {
override void fun() {
}
}
class BornAgainAbstract : Concrete {
abstract override void fun();
}
...
class UltimateShape : Shape <
/ / draw
override final void draw() {

}
..., ,
, .

6.10.

277

,
abstract ,
(. 6.7.1):
cla s s QuiteAbstract {
a b s tra c t {
/ /
void fun();
i n t gun();
double h u n (string );

>
>
abstract,
:
cla s s NiceTry {
a b s tra c t {
void fun();
f i n a l i n t gun(); / / !
/ / !

}
)
abstract :
c la s s Abstractissimo {
a b s tra c t:
/ /
void fun();
i n t gun();
double hun(string );

>
abstract:,
.
, abstract :
a b s tra c t c l a s s AbstractByName {
void fun() {}
i n t gun() {>
double h un (string) {}

}

abstract , , ,
,
. .
. abstract

-
. AbstractByName:

278

6. . -
u n ittest {
auto obj = new AbstractByName; / / !
/ / AbstractByName!

>
c l a s s MakeItConcrete : AbstractByName {

>
u n ittest {
auto obj = new MakeItConcrete; / / 0K

>

6.11.
- ,
.
,
( ).
:
c l a s s Outer {
i n t x;
void f u n ( in t ) {
}
/ /
c l a s s Inner {
i n t ;
void gun() {
fun(x + );

}
>
>
- ... ,
, Inner.gun
Outer? Outer. Inner
Outer,
Outer. ,
?
Outer.Inner , :
u n ittest {
/ /
auto obj = new O uter.Inner;
obj.gun (); / / ,
/ / Outer.x, Outer.fun / / Outer!

)
Outer.Inner,
Outer , ,
, - ,
Outer.Inner ( ), Outer ( x).

6.11.

279


, . ?
, Inner,
Outer.
, Inner
Outer.
Outer.Inner:
unittest {
Outer obj1 = new Outer;
auto obj = obj1.new Inner; / / !
>
new , :
Outer.Inner ,
Outer. ( obj1)
Inner outer,
. ,
Outer ( x),
( x th is.
outer.x).
1
,
. ,
,
Outer Inner:
class Outer {
int x;
class Inner {
int ;
this() {
x = 42;
/ / x - , this.outer.x
assert(this.outer.x == 42);
}
>
}
unittest {
auto outer = new Outer;
auto inner = outer.new Inner;
assert(outer.x == 42); / / inner
/ / outer
}
Outer.Inner Outer,
new th is - . :
1 ++. - . . .

280

6. . -
c l a s s Outer {
c l a s s Inne {
}
Inner _member;
th ls() {
_member = new Inner;
/ / To , this.new Inner
assert(mem ber.outer l s t h i s ) ; / /

}
}

6.11.1.
, ,
. ,
, :
void f u n ( in t x) {
s t r i n g = "";
c l a s s Nested {
double z;
th is() {
/ /
x = 42;
/ /
= "";
/ / -
z = 0.5;

}
}
auto n = new Nested;
a s s e r t ( x == 42);
a s s e r t ( y == "");
a s s e r t ( n . z == 0 . 5 ) ;

}
, , ,
: ,
,
. :
c l a s s C a lculation {
double r e s u l t ( ) {
double n;
retu rn n;

}
>
C a lculation trun cate(double l im it) {
a s s e r t ( l i m i t >= 0);
c l a s s TruncatedCalculation : Calculation {

6.11.

281

o v e rrid e double r e s u l t ( ) {
a u to r = s u p e r .r e s u l t ( ) ;
i f ( r < - l i m i t ) r = - lim it;
e ls e i f ( r > l im i t) r = lim it;
re tu rn r;
}
>

re tu rn new T ru n c a te d C a lc u la tio n ;
}
truncate result Calculation:
.
: ,
result lim it. , ,
TrancatedCalculation truncate,
.
: lim it ,
truncate ?
,
, .
lim it ,
truncate . lim it
- , -
.

.
,
(non-local escapes) - ,
,
1. ,
(
):
.

6.11.2.
: - ,
. ,
, , :
new, . oute r,
.

1
, ,

( ).
. - .
. .

282

. . -


? sta tic
. :
c l a s s Outer <
s t a t i c i n t s;
i n t x;
s t a t i c c l a s s Ordinary {
void fun() {
w r i t e l n ( s ) ; / / ,
/ /
w ri te l n (x ) ; / / !
/ / x!

>
}
}
u n ittest {
auto obj = new Outer.Ordinary; / /

}
,
.

.

6.11.3.
,
, :, .
()
, -
:
c l a s s Widget {
a b s t r a c t u in t width();
a b s t r a c t u in t h eig h t();

}
Widget makeWidget(uint w, u in t h) {
retu rn new c l a s s Widget {
o verride u in t w idth() { return w; }
o verride u in t h e ig h t() { return h; }

};
}


c la s s , ,
, . : 1 8 ( 1 , arg2) B aseC lass, In te rface1, In te rf a c e 2 {}\.- . ..

6.12.

28

, .

.
.
,
[7].

6.12.
D ()
. Java C #,
, ++ E iffel, .
.
,
, - -
,
, , . :

in te r f a c e DuplicativeTransmogrifier : Transmogrifier {
Object duplicate(O bject whatever);

}
DuplicativeTransmogrifier
Transmogrifier, ,
DuplicativeTransmogrifier,
Transmogrifier, dupli
cate. : ,
Transmogrifier, D uplicative
Transmogrifier, .

, , ,
. .
:

in te r f a c e Observer {
void notify(Object data);
}

in te r f a c e VisualElement {
void draw();
>

in te r f a c e Actor {
void nudge();
}

in te r f a c e VisualActor : Actor, VisualElement {


void animate();

284

6. . -

)
class S p rite : VisualActor, Observer {
void draw() {
}
void animate() {
}
void nudge() {
}
void notify(O bject data) {
}
)
. 6.4
. , -
.

. 6.4. ,

Sprite2. Sprite2 ,
VisualActor Actor,
Observer VisualActor Sprite2
Actor. . 6.5.

. 6.5. (
Sprite2 Actor). ,
,

6.12.

285


, .
,
,
Sprite2.
, ,
. ,
ObservantActor, Observer
Actor:
interface ObservantActor : Observer, Actor {
void setA ctive(bool a c tiv e );
}
interface HyperObservantActor : ObservantActor {
void setHyperActive(bool hyperActive);
}
Sprite3, Hyper
ObservantActor VisualActor:
class Sprite3 : HyperObservantActor, VisualActor {
override void notify (O bject) { .. }
override void setA ctive(bool) { .. }
override void setHyperActive(bool) {
}
override void nudge() {
}
override void animate() {
}
override void draw() {
}
>
(. 6.6). Sprite3
HyperObservantActor, VisualActor,
Actor (
). , -
.
,
D .
?
, ?
, ,
,
. ,
. , ,
;
(
- ),
,
.
:

286

6. . -

,
.

. 6.6. (
Sprite3 Actor).
,
HyperObservantActor Sprite3 Actor .
.
-

.
, :
, ,
, . ,
, ,
. ,
(,
),
.
,
, -
Scala ( , ,
). D
,
. , .

6.13.

287

6.13.
, Shape.
, Shape,
. ,
,
, : ,
DBObject.
class DBObject {
private:
. . . / /

public:
void s a v e S ta te ( ) {
void loa dS ta te () {

}
}

>
-, ,
,
StorableShape, Shape DBObject
.
StorableShape. StorableShape
Shape,
- DBObject.
, D ,
.
, ,
.
, ,
- -
. , , - a lia s th is.
:
class StorableShape : Shape {
private DBObject _store;
alias _store th is ;
this() {
_store = new DBObject;
}
>
StorableShape Shape,
DBObject.
StorableShape DBObject
StorableShape, _store
. , DBObject,
th is th is._store. :

288

. . -

unittest {
auto s = new StorableShape;
s.draw();
s .s a v e S t a te ( ) ;

//
//
//
Shape sh = s;
//
DBObject db
s; / /

Shape
DBObject
s ._ s to r e .s a v e S ta te ( )
"" ->
DBObject db = s ._ sto re

}
, StorableShape DBObject, _store - DBObject StorableShape.
a lia s th is,
,
1.

6.13.1.

, ? ,
StorableShape . ,
a lia s th is, StorableShape DBObject,

DBObject. , Shape
, , DBObject.saveState? _store ,
- , Storable
Shape _store, ,
, . ,
.
, Storable
Shape, - _store new DBObject.
_store Storable
Shape, DBObject. ,
, MyDBObject
StorableShape.
StorableShape ,
. , MyDB
Object StorableShape,
,
. !
-,
, :
. (.
6.11) 1 ,
a l i a s th is . - . . .

6.13.

289

, deu s ex m ach in a1. ,


( Java)
a lia s th is.
a lia s th is
. , ,
DBObject.
DBObject,

DBObject Sto
rableShape. ,
.
c la s s StorableShape : Shape {
p riv ate c l a s s MyDBObject : DBObject {
override void sa v eS tate() {
/ / DBObject StorableShape

}
}
p rivate MyDBObject _store;
a l i a s _sto re th is ;
th is() {
/ /
_store = this.new MyDBObject;

}
}
_store
StorableShape. 6.11,

( th is) .
this.new MyObject ,
th is MyDBObject. ( ,
this. ,
.)
,
DBObject StorableShape.
, DBObject Shape
_name:
c lass Shape {
protected s tr in g _name;
a b s tra c t void draw();

1 Deus ex machina ( ) - : ,
(
) .
- . - ..

290

. . -

}
c l a s s DBObj0 c t {
protected s t r i n g _name;
void sa v eS tate() {
}
void lo a d S ta te () {
}

}

MyDBObject, StorableShape, DBObject._name
StorableShape._name. ,
MyDBObject _name,
DBObject._name.
c l a s s StorableShape : Shape {
p r iv a t e c l a s s MyDBObject : DBObject {
override void sa v eS tate() {
/ / Shape._name Shape
this.o u te r._ n am e = "";
/ / DBObject._name -
_name = "B'';
/ /
assert(super._nam e == "B");

>
>
p r iv a te MyDBObject _store;
a l i a s _ sto re t h is ;
th is() <
_ sto re = new MyDBObject;

}
>

6.14.


, . ,
, .
(StackInt, StackDouble, StackWidget, ...)
.
D:
i n te r f a c e Stack(T) <
0property bool empty();
0property r e f T to p ();
void push(T value);
void pop();

>

6.14.

291

(T) Stack .
T , .
Stack ,
. !,
:
unittest {
alias S ta c k !( in t) StackOfInt;
alias S ta c k !in t SameAsAbove;
}
, (
Stack), .
.
( - ). , StackImpl, T,
Stack .
:
import s td .a rra y ;

class StackImpl(T) : Stack!T {


private T[] _store;
eproperty bool empty() {
return _store.empty;
}
eproperty ref T to p () {
assert(!empty);
return _store.back;
>
void push(T value) {
sto re ^= value;

}
void pop() {
assert( !empty);
_store.popBack();

>
}
StackImpl , :
unittest {
auto stack = new StackImpl!int;
assert(stack.em pty);
s t a c k . push(3);
a s s e r t( s ta c k .t o p == 3);
s t a c k . push(5);
a s s e r t ( s t a c k .t o p == 5);
stack.pop();
a s s e r t ( s t a c k .t o p == 3);

292

6. . -
stack.pop();
a s s e r t ( s t a c k . empty);

}
,
, StackIm pl!int-
, .
Stack! in t, StackImpl(T) T
int .

6.14.1.
,
, .
(
) 5.3
. :
,
(, Object), (
) .
,
( )
(
).
. Java C #
.
StackImpl
. , ,
:
StackImpl!int StackImpl!double . , ,
Stack!T StackImpl!T.
, ,
T, . ,
Stack StackImpl T,
.
, Stack StackImpl,
; ,
- , , .
- ,
. :
Stack!int Stack!double ,
. ,
. [14,1, 49].
( ++)
-. Stack -
, . (

6.14.

293

: - , -
.) Stack!int, Stack! string,
, ,
, .
, Stack
T ,
Stack. , ,
, ,
. ,
,
, .
D , , Stack! int
Stack!double- , StackImpl!int StackImpl!double . . ( ,
, , ,
Stack .)
StackImpl
,
, ,
.
(
D ,
++ ).
, .
StackImpl,
.
, StackImpl.
StackImpl empty, back, ^= popBack.
StackImpl:
c la ss StackImpl(T, Backend) : Stack!T {
priv a te Backend _store;
property bool empty() {
return _store.empty;

}
property ref T top () {
assert(!em pty);
return _store.back;

}
void push(T value) {
_store ^= value;

}
void pop() {
assert(!em pty);
_store.popBack();

}
}

294

6. . -

6.15.
1
, D
. - ,
. D

( . allocate - , ) -
- .
:

im p o rt s t d . c . s t d l i b ;
im po rt c o re .e x c e p tio n ;
c la s s S td c C la ss {
n e w (siz e _ t o b j_ s iz e ) {
void* p tr = m a llo c (o b j_ s iz e );
i f ( p t r i s n u ll)
throw new OutOfM em oryError(_ FILE_ , _ LINE_ );
r e tu rn p tr;
}

d e le te (v o id * p t r ) {
i f (p tr)
fre e (p tr);
>
>
new
.
(void*). -
size_ t.
malloc .

, null.
.
null, ,
- , .
, return
.
delete
, .


,
, . - . . .

295

6.15.

, ,
, .
. , .

++ :
StdcClass obj = new StdcClass();

delete obj;
. ,
D, .
,
, d elete. new
delete.
, .
.
,

:
import s t d . c . s t d l i b ;
import core.exception;
class StdcClass {
new(size_t obj_size) {
void* p tr = m alloc(obj_size);
i f ( p tr is null)
throw new OutOfMemoryError(
return ptr;

FILE

LINE

);

FILE

LINE

);

}
new(size_t, void* p tr ) <
i f ( p tr is n u ll)
throw new OutOfMemoryError(
return ptr;

}
delete(void* p tr ) {
i f ( p tr )
free(p tr);

>
}
.
s t a t i c void[_tr a i t s ( c l a s s I n s t a n c e S i z e , StdcC lass)] data = void;

auto i_1 = new (data.ptr) StdcC lass(); / /


/ /

296

6. . -

auto i_2 = new StdcClass(); / /


delete i_2;
, .
( ) ,
.
new. .

, , ,
,
.
emplace:
import std.conv;
class {
int i;
th is() { i = 42; }
>
unittest {
void[_tr a i t s ( c l a s s I n s t a n c e S i z e , )] data = void;
auto = emplace!C (d ata[]);
a ssert(c.i == 42);
}
, , - :
,
, (
, -) ,
,
core.memory.GC.addRange().
,
, ,
.
,

, ,
. !

6.16. scope1
++
.
,
.
1
,
, . - . ..

6.16. scope

297

,
- , ,
.
,
. RAII
(Resource A cquisition Is In itialization -
),
, .
RAII D
, ,
scope(exit). D
, R AII scope.
,
.
, scope - ,
:
scope obj = new SomeClass(arg_1);
scope SomeClass obj_2 = new SomeClass(arg_1);

.
,
. ( ,
),
.
. ,
delete.
++, D scope .
,
, scope .
, :
Object oo() {
scope t = new Object;
return t; / /

}
scope ,
:
Object foo()

{
scope t = new Object;
Object p = t;
return p; / / ,
/ /

>
, D scope.
scope scope.

298

6. . -

scope- .
scope scope.
scope , scope
scope.
(-).
, ,
5- , SHA-256
, .
Import s t d . s t d i o ;
a b s t r a c t scope c l a s s Digest

<
a b s t r a c t void update (v oid[] data);
a b s t r a c t ubyte[] r e s u l t ( ) ;

}
c l a s s Md5: Digest { / / scope

}
5- -
:
ubyte[] c a lc u la te H a sh (strin g filename)

{
scope d ig e s t = new Md5();
auto fd = File(filenam e, "r");
ubyte[] buff = new ubyte[4096];
ubyte[] readBuff;
do {
readBuff = fd.rawRead(buff);
d i g e s t . u p d ate(readBuff);

}
while (readB uff.leng th);
return d i g e s t . r e s u l t ( ) ;

}
void m a in ( str in g [] args)

<
ubyte[] hash = ca lc ulateH ash(args[1]);

}
scope

:
scope c l a s s { )
Object saved;
void save(Object ) {

299

6.17.
saved = ;

>
void derp() {
scope = new ;
save(c);

}
void main() {
d e rp ();
/ / saved?

>
scope .
,
.
, . , scope
, ,
. .
, .

, .
.
scope scope
, .
scoped!T:
import std.typecons;
unittest {
c la s s { i n t x; }
auto a1 = scoped!A();
auto a2 = scoped!A();
a1.x = 42;
a2.x = 53;
a s s e r t( a 1 .x == 42);

}
scoped!T, std.typecons,
,
( D).

6.17.
- -
D.
.
.
, -

300

. . -

.
, .
,
( ).
- Object,
object, D. Object
, object - ,
.
,
, ,
.
D ,

.

, ,
.
. ,

.
-, -

.
,
, :
-
. ,
- .
-, = b
b, !
, ,
,
D (. 4). , ,
, ,
,
, - .
- ,


. , in t,
( ).
, BigInt, : = b ,
int.

302

7.

-, , ,
(
, ,
, . .). ,
,
, close dispose.
scope (. 3.13),
,
- .
-, -
,

.
D ,
.
D (-,
, ),
enum ( ),
(
) ,
a lia s . .

7.1.
, . - int: int 4 ,
. int
, int
1.
, ,
. -
int.
, (. 6.2),
,

. - -,
, , int:
,
, .
, ,
:

, a lia s ,
( . 7.4).

303

7.1.

c la s s s tru c t;

, :BaseType
:Interface, ,
super;

-
(
fin a l, );

synch ronized (. 13);

t h i s ( )
(. 7.1.3.1);

(postblit constructor) t h i s ( t h i s ) (. 7.1.3.4);

protected (
-).

:
s t r u c t Widget {
/ /
enum f u d g e F a c t o r = 0 . 2 ;
/ /
s t a t i c i m m u t a b l e d e f a u l t N a m e = "";
/ / ,
/ / W i d g e t
s t r i n g na me = d e f a u l t N a m e ;
u in t width, h e ig h t ;
/ /
s t a t i c double howFudgy() {
return fudgeFactor;

}
/ /
void changeN am e(string an other) {
na me = a n o t h e r ;

>
}

7.1.1.

.
, ,
6.2.
, :
class {
i n t x = 42;
double = 3.14;

304

7.
struct S {
i n t x = 42;
double = 3.14;

}
unittest {
c 1 = n e w ;
S s1;
/ / n e w S:
a u to c2 = c1;
au to s2 = s1;
c 2 . x = 100;
s 2 . x = 100;
a s s e r t ( c 1 . x = = 1 0 0 ) ; / / c 1 c 2 . . .
a s s e r t ( s 1 . x == 4 2 ) ; / /
. a s 2 - s1

>
,

.
. , -
, - - . . 7.1
c2 s2 .

. 7.1. auto c2 = 7; - c1 auto s2 = s1;


- s1 -,
- , -
c1 c2, ,
s1 s2 .
- (
a l i a s , ; .
7.4),
, s1 i s null
.

7.1.2. -
s t r u c t ,
.
struct S {
i n t , b, ;

305

7.1.
d o u b l e x , , z;

)
void fun(S s ) {

/ / f u n

}
-
ref (. 5.2.1):
v o id f u n ( r e f S s ) { / / fun

>
ref, , t h i s
S ref S.

7.1.3. -
-, -
(lifetim e).
- () .
-, ,
:
im port std.m ath;
stru ct Test {
double = 0.4;
d o u b l e b;

}
unittest {
/ / , ,
/ /
a u t o t = T e s t ( );
a s s e r t ( t . a == 0 . 4 && I s N a N ( t . b ) ) ;

}
Test() -,
. , t . a
0.4, t.b
double.init.
Test(1) Test(1.5, 2.5)
. :
unittest {
au to t1 = T e s t (1 );
a s s e r t ( t 1 . a == 1 && I s N a N ( t 1 . b ) ) ;
auto t2 = T e st(1 .5 , 2.5);
a s s e r t ( t 2 . a = = 1 . 5 && t 2 . b == 2 . 5 ) ;

>

306

7.

,
- Test ('>), ,
- new lest(<apryMeHTbi>). D
new -, new
, (
).

7.1.3.1.
,
(. 6.3.1):

stru ct T e st {
double = 0 . 4 ;
double b;
th ls(d o u b le b) {
t h i s . b = b;
}
}

u n ltte st {
a u to t = T e s t ( 5 ) ;
}

,
:

a u to t 1 = T e s t ( 1 . 1 , 1 . 2 ) ; / / !
/ / , T e s t ( d o u b l e , d o u b l e )

:
:

a u to t 2 = T e s t ( ) ;

/ / ,
/ / " "

,
:

stru ct T e st {
double = 0 . 4 ;
double b;
t h i s ( ) { b = 0 ; } / / !
/ / !

}
? - T.init -
, .
, ,
. ( T.init -
null, , .)
:
- .

307

7.1.

7.1.3.2.
6 .3 .2 cla ss
struct:
s t r u c t Widget {
t h i s ( u i n t height) {
th is ( 1 , height);

/ /

}
t h i s ( u i n t w idth, u in t height) {
th is .w id th = width;
t h i s . height = h e ig h t;

}
uint width, height;

>
, - .
,

.

7.1.3.3.

(. 6.3.3).
, -
. -
T :
1. T.init , ,
(- memcpy).
2. , .

= void, ,
,
(
Transmogrifier
6.3.3).

7.1.3.4. this(this)
, ,
(private) A P I
:
s t r u c t Widget {
priv ate i n t [ ] array;
t h i s ( u i n t length) {
array = new in t[ le n g th ];

308

7.
in t g et(size_t o ffse t) {
retu rn a r r a y [ o f f s e t ] ;

>
void s e t ( s i z e _ t o f f s e t , i n t value) {
a r r a y [ o f f s e t ] = value;

>
}
Widget, , :
Widget
. :
u n ittest {
auto w1 = Widget(10);
auto w2 = w1;
w1.set(5, 100);
w2.set(5, 42);
as se r t( w 1 .g e t(5 ) == 100);

/ / w1.array[5]!
/ / !?!

}
? w1 w2 ,
, ,
.
;
(. 4.1.4). w1
w2 ,
. ,
, ,
, (
) ( )1.
,
,
. :
s t r u c t Widget {
p r iv a t e i n t [ ] array;
t h i s ( u i n t length) {
a rra y = new i n t[ le n g th ] ;

>
/ /
th ls (th is) {
a rra y = array.dup;

)
/ /
i n t g e t ( s i z e _ t o f f s e t ) { return a r r a y [ o f f s e t] ; )
void s e t ( s i z e _ t o f f s e t , i n t value) { a r r a y [ o f f s e t] = value; }

309

7.1.


.
, :
1.
.
2. , (
, , , ...),
t h i s ( t h i s ) ,
( ).
3. t h i s ( t h i s ) .
postblit con struc
tor blit - block
transfer, .

.

, , ,
- -
. , ,
:
u n ittest {
auto w1 = Widget(10);
auto w2 = w1;
/ / th is(th is)
w1.set(5, 100);
w2.set(5, 42);
a s sert(w 1.get(5) == 100); / /

w2

}

-
. , Widget
:
void fun(Widget w) {
w.set(2, 42);

/ /

/ /

}
void gun(ref Widget w) {
w.set(2, 42);

}
u n ittest {
auto w1 = Widget(10);
w1.set(2, 100);
fun(w1);
/ /
a ssert(w 1 .g et(2 ) == 100); / /
gun(w1);
/ /

310

7.
a s s e rt(w 1 .g e t(2 ) == 42);

/ /

>
( )
.
:
- ,
. , ,
Widget ,
:
s t r u c t Widget2 {
Widget wl;
i n t x;

}
s t r u c t Widget3 {
Widget2 w2;
s tr in g name;
th is(th is) {
name = name ~ " (copy)'';

)
>
, ,
Widget, , ,
Widget.
Widget2 th is(th is)
w1, , Widget2
. , Widget3
th is(th is) - w1 w2.
:
u n ittest {
Widget2 ;
a.w1 = Widget(10);
//

auto b = ;
//
t h i s ( t h i s ) b.w1
a s s e r t( a .w 1 .a r r a y ! i s b.w1.array);
/ /
Widget3 ;
c.w2.w1 = Widget(20);
auto d = ;
/ / t h i s ( t h i s ) d.w2.w1
assert(c .w 2 .w 1 .a rra y ! i s
d.w2.w1.array); / /

}
,
th is(th is), ,

- ,
-.

311

7.1.

7.1.3.5. this(this)
?
.
( ++)?
/ / D
stru ct S {
th is (S another) {
}
/ /
t h i s ( r e f S another) {

}
++ ,
++ - .
, ++ ,

(copy elision).
, ,
, .
++ ,
r-,
, -
.
D
. , D
,
:
, .
,
- ,
. , D .
D ,
, , ,
.
(,
) ,
.

:
th is(th is)
.
,
( ,
-), ,
-.
,
th is(th is), ,

312

7.

.
, , , Widget
( ) :
Widget hun(uint x) <
return Widget(x * 2);

}
unittest {
auto w = hun(1000);
}
: Widget
hun, w,
th is(th is).
: D ,
w
, hun? ,
, hun ,
. ,
, . ( )
:
Widget iu n (u in t x) {
auto r e s u l t = Widget(x * 2);

return r e s u lt;
>
unittest {
auto w = iun(1000);
}
result
, iun , th is(th is)
. , :
void jun(Widget w) {
}
unittest {
auto w = Widget(1000);
. . / / ,jun(w );
/ / *2>

>
,
th is(th is). , <2> w,

7.1.

313

u n ittest jun
1.
D
:

r- , .
th is(th is) ,
r- ( ,
hun ).

,
,
,
th is(th is) .

,
.


. move std.algorithm
:
import std.algorithm ;
void kun(Widget w) {

)
unittest {
auto w = Widget(1000);
. . . / / - ,
/ / move
kun(move(w));
assert(w == W id g et.in it); / /
.. / / >

)
move , w ,
,
Widget. , ,

Widget.init (. 7.1.3.1).
.

7.1.3.6.
^ t h i s ( ) :
import s td . s td i o ;
stru ct S {

1 , <}> w,
<2'.

314

7.

int x = 42;
'th is() {
w riteln (" C T p yK T ypa

S ", x, " . !");

}
)
void main() {
writeln("Co3flanne S .");

<
S object;
w r it e ln (" B H y T p n

");

}
writeln("BHe ");

}
:
S .

S 42 . !
.


(scoped lifetim e),
. :

,
, (
) -,
;
,
,
;

, ,
; ,
(. 11.3);

, ,
,
.

^this
-, ,
,
.
, ,
,
, ( ),
.
-
.

315

7.1.

7.1.3.7.
- ,
. , :
import std.conv, std.stdio;
struct S {
private string name;
t h is (str in g name) {
writeln(name, " .");
th is . name = name;

>
^this() {
writeln(name, " .");

}
}
void main() {
auto obj1 =
foreach (i;
auto obj
}
auto obj2 =
)

' ");
0
3) {
= S(text("o6beKT " i ) ) ;
");

:
,
0 ,
0 .
1 ,
1 .
2 ,
2 .
.
,
.

, , ,
.
.
-
1();. clear
6 .3 .5 .
-. - clear
: ,
.in it .
, , -
.

316

7.

7.1.4.

.
, 6.3.6.
im port s t d . s t d i o ;
struct {
s t a t ic ^ th is() {
w r i t e l n ( " " );

}
sta tic th is() {
w r i t e l n ( " n e p B b m ");

>
sta tic th is() {
w r i t e l n ( " B T o p o n ");

}
sta tic 'th is () {
w r i t e l n ( " B T o p o n " );

}
}
void m a in () {
writeln("BHHMaHne,

mai n");

>
.


main .
main
,
. :


, m ain


, ,
.

6 .3 .6 .

317

7.1.

7.1.5.
-,
.
, , .
S th is
( ref S).
, :
,
,
.
void fu n (in t x) {
a s s e r t( x != 0);

}
/ /
stru ct S {
i n t x = 1;
s t a t i c i n t = 324;
void f u n (in t x) {
a s s e r t( x == 0);
/ / x
a s s e r t ( t h i s . x == 1); / / x

}
void gun() {
fun(0);
.fun(1);

/ / fun
/ / fun,
/ /

}
/ /
u n ittest {
S obj;
obj.gun();
a s s e r t( y == 324);
/ / ,
/ / " "
/ /

>
>
, ,
. ,
, ,
.
,
: ,
S,
.

318

7.


. opAssign,
=, opEquals,
== !=, opCmp,
<, <=, >= >. , 12,
,
: ,
.

7.1.5.1.
, :
s t r u c t Widget {
Widget wl, w2;

} / / , 7.1 .3 .4

w1 = w2;


. Widget
, 7.1.3.4. ,
Widget in t[],
, Widget.
w2 w1
w2.array w1.array,
,
.
,
.
,
opAssign. , lhs opAssign
, lhs = lhs.opAssign(rhs),
lhs rhs ,
. Widget.opAssign:
s t r u c t Widget {
p r iv a te i n t [ ] array;
/ / th is(u in t), th is (th is ), . .
r e f Widget opAssign(ref Widget rhs) {
array = rhs.a rray .dup ;
return th i s ;

}
}
th is,
- w1 = w2 = w3,
w1.opAssign(w2.opAssign(w3)).
. :

319

7.1.
Widget w;
w = Widget(50); / / !
/ / r - Widget ref Widget!

, opAssign ,
, ref Widget, 1- Widget.
1- -
, Widget :
import std.algorithm ;
s t r u c t Widget {
priv ate i n t [ ] array;
/ / th is (u in t), th is (th is ), ..
ref Widget opAssign(ref Widget rhs) {
array = rhs.array.dup;
return th is ;

}
ref Widget opAssign(Widget rhs) {
swap(array, rh s.a rra y );
return th is ;

, r-,
.dup. ? , r- ( ) -
opAssign:
,
. ,
rhs.array, .
rhs.array this.array. opAssign
, rhs th is
, th is , rhs, -
.

opAssign: , rhs ,
(1- -).
1-, ,
.
- .dup, opAssign
,
, ,
.
/ / Widget
ref Widget opAssign(ref Widget rhs) {
i f (a rra y .le n g th < r h s .a r r a y .le n g th ) {
array = rhs.array.dup;
} e ls e {

320

7.
/ /
a r r a y .le n g th = r h s .a rr a y .le n g th ;
/ / array (. 4.1.7)
a r r a y [ ] = r h s .a r r a y [ ] ;

}
return t h i s ;

7.1.5.2.
-
* - == !=.
fa lse,

, true.
s t r u c t Point {
i n t x, ;

>
u n ittest {
Point , b;
a s s e r t ( a == b);
a.x = 1;
a s s e r t ( a ! = b);

}
,
opEquals:
import std.math, s t d . s t d i o ;
s t r u c t Point {
f l o a t x = 0, = 0;
/ /
bool opEquals(ref const Point rhs) const {
/ /
return approxEqual(x, rh s.x ) && approxEqual(y, rhs.y);

)
}
u n itte st {
Point , b;
a s s e r t ( a == b);
a .x = 1e-8;
a s s e r t ( a == b);
a .y = 1e-1;
a s s e r t ( a ! = b);

}
opEquals (. 6.8.3)
opEquals :
- .

7.1.

321

- opEquals.
,
opEquals: ,
. , Point.opEquals
, .

Point,
.
.
,
opEquals, ,
opEquals .
, Point:
s t r u c t Rectangle {
Point leftBottom, rightTop;

}
u n ittest {
Rectangle , b;
a s s e r t ( a == b);
a.leftB ottom .x = 1e-8;
a s s e r t ( a == b);
. rightTop. = 5;
a s s e r t( a != b);

}
b Rectangle == b

a.leftB ottom == b.leftBottom && a.rightT op == b.rightTop

:
. leftBottom .opEquals(b.leftBottom) &&
. rightTop.opEquals(b.rightTop)

,
(. e. leftBottom right
Top), ,
, ,
, && (short
circuit evaluation).

7.1.6.

.
(. 7.1.7)
.

322

7.

th is,
.
,
(. 5.2.4), ,
,
.
in p o r t s t d . s t d i o ;
s t r u c t Point {
p r iv a t e i n t x, ;
p r iv a t e s t a t i c s t r i n g formatSpec = "(%s %s)\n";
s t a t i c void setFormatSpec(string newSpec) {
/ /
formatSpec = newSpec;

}
void p r i n t ( ) {
writef(formatSpec, x, );

}
}
void main() {
auto pt1 = Point(1, 2);
p t1 .p rin t();
/ / ,
/ / Point pt1
Point.setFormatSpec("[%s, %s]\n");
auto pt2 = Point(5, 3);
/ / Point
p t1 .p rin t();
p t2 .p rin t();

}
:
(1 2 )
[1 , 2 ]

[5,

3]

7.1.7.
private (.
6.7.1), package (. 6.7.2), public (. 6.7.4) export (.
6.7.5) , . protected
,
.
.
:

323

7.1.
stru ct S {
priv a te i n t ;
package i n t b;
public i n t ;
export i n t d;

//
//
//
//


/ / (, )

}
, export ,
,
.

7.1.8.
.
, - ,
.
s t r u c t Tree {
private:
c l a s s Node {
i n t value;
a b s tr a c t Node l e f t ( ) ;
a b s tr a c t Node r ig h t( ) ;

>
c l a s s NonLeaf : Node {
Node _ l e f t , _right;
override Node l e f t ( ) { return _ l e f t ; }
override Node r ig h t( ) { return _ r i g h t ; }

}
c la s s Leaf : Node {
override Node l e f t ( ) { return n u ll; }
override Node r i g h t () { return n u ll; }

}
/ /
Node root;
public:
void add (in t value) {
bool se a r c h ( in t value) {

}
}

}
...
s t r u c t Widget {
private:
s t r u c t Field {
s tr in g name;
uint x, ;

}
F ield [] f ie ld s ;

324

7.
public:

>
... , .
c l a s s Window {
s t r u c t Info {
s t r i n g ;
Window parent;
Window[] children;

}
Info g e tIn f o ( );

)
, ,
, ,
outer -
.
- .

7.1.9. ,
, 6.11.1:
, ,
.
.
,
,
,
.
D ,
, , , .

:
void f u n ( in t ) {
i n t b;
s t r u c t Local {
i n t ;
i n t sum() {
/ / ,
/ / Local
return + b + ;

}
>
Local obj;
i n t x = obj.sum();
/ / ( v o id * ).s iz e o f -
/ / l n t . s i z e o f -

325

7.1.
a s s e r t( L o c a l.s iz e o f == ( v o id * ).siz e o f + i n t . s i z e o f ) ;

}
u n ittest {
fun(5);

}
,
,
b . -
Local 4 , , 8 ( 32- ) - 4 .
,
Local s ta tic
struct - Local ,
b.
, ,
,
.
,
. ,
,
.

7.1.10. .
@disable
,
- a lia s th is,
6.13. a lia s th is
. , ,
Final, -
, Final !
Final:
import s td . s td i o ;
c l a s s Widget {
void p r i n t ( ) {
writeln("npnBeT, Widget. , , .);

I
}
u n ittest {
auto = Final!Widget(new Widget);
a.p rin t();
/ / ,
auto b = ;
/ / , b
/ / Widget
= b;
/ / !
/ / opAssign(Final!Widget) !

326

7.
= new Widget; / / !
/ / -,
/ / g et()!

}
Final - ,
.
.
- . ,
,
, Final
. @disable:

s t r u c t Final(T) {
/ /

d isa b le vo id opAssign(Final);
>
@disable
, .
. Final!T,
a lia s th is Final(T) T,
1-.
:
/ /
s t r u c t Final(T) {
p r i v a t e T payload;
t h i s ( T bindTo) {
payload = bindTo;

}
/ /
e d i s a b l e vo id opAssign(Final);
/ / Final(T) T
a l i a s payload t h i s ;

}
Final payload,
. , ,
opAssign, .
, ,
Final!T, payload (- private),
.
Final - a lia s payload th is;.
- :

c la ss {
i n t value = 42;
t h i s ( i n t x) { value = x; }
}

327

7.1.
unittest {
auto v = Final!A(new A(42));
void sneaky(ref ra) {
ra = new A(4242);

I
sneaky(v); // - - ..
a s s e r t( v .v a lu e == 4242); / / ?!?

}
a lia s payload th is : ,
Final!T
, oe.payload (
o6beKT.payload
a lias). .payload
, ,
1-. 1-
sneaky , , sneaky
v.
, -.
, ,
payload, .
- ( @perty), payload :
s t r u c t Final(T) {
priv ate T payload;
th is (T bindTo) {
payload = bindTo;

}
/ / , opAssign
priv ate void opAssign(Final);
/ / Final(T) T,
/ / payload
eproperty T g e t() { return payload; }
a l i a s get th is ;

}
, get
T, ref . , ,
payload, ( ,
const immutable; . 8).
Final . -,
T , Final! T . -,
Final!T
,
. , , -
Final, ,
sneaky(v) : - (
v v.get) ref ,
sneaky .

328

7.

( ,
), . ,
, Final, a lia s get th is,
Final,
, ,
Final. ,
Final!Widget, Widget get:
c l a s s Widget {
p r iv a te i n t x;
eproperty i n t g e t () { return x; }

}
u n ittest {
auto w = Final!Widget(new Widget);
auto x = w.get; / / Widget Final, in t Widget

}
,
.
:
s t r u c t Final(T) {
p r iv a t e T Final_payload;
th is ( T bindTo) <
Final_payload = bindTo;

}
/ /
e d is a b le void opAssign(Final);
/ / Final(T) T,
/ / payload
0property T F in al_ g e t() { return Final_payload; }
a l i a s Final_get th i s ;

}

. (,
, .)

7.1.11. .
-? D
:
, ,
^padding).
:
stru ct {
char ;
i n t b;
char ;

329

7.1.


, , b
1 ( char 1 ).
,
4 8 ,
, , 4
8 . ,
, 8. b
. b,
, b,
. ,


,
( ) [28].
:
.

. ,
.
, ,
,
. . 7.2
.
------- i------- i------- i------< . I*/A S \ / /

\ '\ > y ^
____ \'~y'yyC/ ' \ / / / , ____ i_____i_____i_____

: /^ y ^ ^ x X x
r 4/ / A / ' '

. 7.2. .
- , .
, 6
50%
(
).
,
,
. int
, - char.
64 , 2 .

.

( ,
).

330

7.

. o f f s e t o f ,
:
import s t d . s t d i o ;
stru ct {
char ;
i n t b;
char ;

>
void main() {
x;
w ritefln("% s% s% s''

x . a . o f f s e t o f , x . b .o f f s e to f , x .c .o f f s e t o f ) ;

}
0 4 8,
, . 7.2.
,
, A . a . o f f s e t o f
. : A . i n i t . a . o f f s e t o f

, .
import s t d . s t d i o ;
stru ct {
char ;
i n t b;
char ;

}
void main() {
/ / ,
w ritefln("% s %s %s", A . i n i t . a . o f f s e t o f ,
.i n i t . b . o f f s e t o f , .i n i t . c . o f f s e t o f ) ;

}
D ,
.

7.1.11.1. align
,
, ,
align.

, . align :
class {
char ;
a lig n (1 ) i n t b;

7.2.

331

char ;

}

. (
, .) align
,
.
T
T.alignof. , , b
align(200) align(1),
4, int.alignof.
align :
alig n(1) s t r u c t {
char ;
i n t b;
char ;

}
align
.
align .
T align ,
align(T.alignof),
.

. ,
size_t.
,
, .
, ,
:
s t r u c t Node {
short value;
alig n (2 ) Node* next; / /

}
o6beKT.next = new Node (
o6beKT.next , ),
:
, , , next
.

7.2.
D, ,
.

332

7.

(union) - - ,
. ,
, ,

: ,
.
.
union IntOrFloat {
int _int;
float _float;
}
unittest {
IntOrFloat iof;
i o f . _ i n t = 5;
/ / i o f . _ i n t , i o f . _ f l o a t
a s s e r t ( i o f . _ i n t == 5);
i o f . _ f l o a t = 5.5;
/ / i o f . _ f l o a t , i o f . _ i n t
a s s e r t ( i o f . _ f l o a t == 5.5);

}
int flo a t (4 ),
IntOrFloat .
, ,
_int _float :
_int ,
_ float (, ) .
, union
, , ,
.

,
.
, union
:
.in it,
.
, .in it,
:
unittest {
IntO rFloat io f = { 5 };
a s s e r t ( i o f . _ i n t == 5);

}
union
. :

7.2.

333

u n ittest {
s t a t i c IntOrFloat io f = { _ f lo a t : 5 };
a s s e r t ( i o f . _ f l o a t == 5);

}
, ,
, ,
,
.
, .
, 32- Intel
assert :
unlttest {
IntOrFloat iof;
i o f . _ f l o a t = 1;
a s s e r t ( i o f . _ i r t == Ox3F80_0000);

>
- , ,
,
, .
(, )
. :
import s td .c o n tra c ts ;
s t r u c t TaggedUnion {
enum Tag { _tvoid, _ t i n t , _tdouble, _ ts t r i n g , _ ta rr a y }
priv ate Tag _tag;
priv ate union {
i n t _int;
double _double;
s tr in g _string;
TaggedUnion[] _array;

}
public:
void opAssign(int v) {
_int = v;
_tag = T ag._tint;

)
in t getInt() {
enforce(_tag == T a g ._ tin t) ;
return _int;

>
}
u n ittest {
TaggedUnion ;

334

7.
= 4;
a s s e r t (a .g e t I n t( ) == 4);

}
( enum 7.3.)

union
(d iscrim in a ted union, tagged union),
.
union ,
.
Tag Tag._tvoid, ,
.
opAssign,
.
, opAssign(double), opAssign(string) nopAssign(TaggedUnion[]) getXxx().
union ,
, .

,
( TaggedUnion).
,
, .
, ,
. ,
, cast, -
.
,
.

( cast),
, ,
.

7.3.
, ,
, Java

[8].
- (
++) enum . D
,
.

335

7.3.

. enum -
,
:
enum
mega = 1024 * 1024,
pi = 3.14,
euler = 2.72,
greet = "Hello";

enum ,
auto, pi euler
double, greet - string.
,
enum:
enum float verySmall = 0.0001, veryBig = 10000;
enum dstrin g wideMsg = "Wide load";
;
, . ,
- , pi,
3.14:
auto x = pi;
/ / ,
auto = pi * euler; / / ,
euler = 2.73;

void fun(ref double

x double
double

/ / !
/ / !
x)

}
fun(pi);

/ / !
/ / 3.14!

,
int double string .
enum? : enum
.
:

,
disable th is(th is) (.
7.1.3.4).


.
;
.
cla ss,
new

336

7.

( null),
new .
, .
struct:
s t r u c t Color {
ubyte r, g, b;

>
enum
red = Color(255, 0, 0),
green = Color(0, 255, 0),
blue = Color(0, 0, 255);

, , green,
,
Color(0, 255, 0).

7.3.1.
,
:
enum 0ddWord { a c in i, alembicated, prolegomena, aprosexia }


;
,
. :
0ddWord w;
assert(w == 0ddWord.acini); / /
//
w = 0ddWord.aprosexia;
//
//
//
i n t x = w;
//
a s s e r t ( x == 3);
//


- acini.

(, , )
,
0ddWord in t, ,
: 0, 1, 2,

, , in t. :
enum 0ddWord : byte { a c in i, alembicated, prolegomena, aprosexia }

(byte 0ddWord)
,
.
double real,
: 0, 1 . .
0ddWord , string,
,
,
.

7.3.

337

. -
, ,

. :
enum E { , b = 2, , d = -1, e, f }
a s s e r t( E .c == 3);
a s s e r t( E .e == 0);


( E.a E.e), .
, -

:
enum F : f l o a t { = 1E30, b, , d }
a s s e r t( F . a == F.d); / /

, in t,
flo a t, 16_777_216,

, flo a t.

7.3.2.
E : E.init (
, E), E.min (
E ) E.max (
E ). ,
E ,
<.
enum min, max in it,
:
, .
:
? ,
, ,
. :
Enum
__traits(allMembers, Enum),
Enum string.
, ,
. ,
, toString, ,
. .
s tr in g toString(E)(E value) i f (is(E == enum)) {
foreach (s; __traits(allM embers, E)) {

338

7.

i f (value == mixin("E." ^ s)) return s;


}
return null;
>
enum OddWord { acini, alembicated, prolegomena, aprosexia >
void main() {
auto w = OddWord.alembicated;
assert(toString(w) == "alembicated");
}
mixin("E." ^ s) - mixin.
mixin , ,

. E,
s
. s
"acini", "alembicated", ..., "aprosexia".
, "E.acini" ..,
mixin ,
. ,
, mixin, toString
. value,
toString ,
, null.
toString std.conv
,
. ,
: to!string(w) toString(w),
( to!dstring(w)
to!byte(w) ..). ,
;
to!OddWord("acini") OddWord.acini.

7.4. alias
size_ t - ,
, .
size_ t , uint
ulong (32
64 ).
object.di,
( , ) D,
:
alias typeof(int.sizeof) size_t;

339

7.4. alias

.siz eo f ;
int. int ;
, ,
typeof. ,
uint 32- ulong 64- .
, a lia s size_ t uint
ulong.
a lia s
:
allas <> <>\
<>
, . , , -
- ,
. :
import s td . s td i o ;
void f u n (in t) {}
void fu n (s trin g ) {}
i n t var;
enum E { e >
s t r u c t S { i n t x; }
S s;
unittest
alias
alias
alias
allas
alias
alias
alias
allas
alias

{
object.O bject Root;
std phobos;
s t d . s t d i o io;
var sameAsVar;
E MyEnum;
E. e myEnumValue;
fun gun;
S.x f ie l d ;
s.x s f ie l d ;

//
//
//
//
//
//
//
//
//

}
:
, .
, :
- .

,
. ,
immutable(char)[]
string. ,
.
a lia s
, . :

340

7.

alias int Int;


alias I n t MyInt;
, :
MyInt Int
in t, Int
.
a lia s ,

(. 5.5.2).
a lia s
. :
/ / -
class Container(T) {
alias T ElementType;

}
unittest {
C o n ta in e r!in t container;
C ontainer! in t . ElementType element;

}
ElementType, Con
tainer, -
, T Container.
T Container,
: Container!int.T .
, a lia s
s ta tic if. :
/ / o b j e c t . d i
/ /
static i f ( s i z e _ t . s i z e o f == 4) {
alias int p t r d i f f _ t ;

} else {
alias long p t r d i f f _ t ;
>
/ / p t r d i f f _ t

ptrdiff_t
,
. ,
, sta tic if.

7.5. ( template)

341

7.5.
( template)
,
( ++
Java C #), - (. 5.3),
(. 6.14) ,
,
. -
, ,
. , (
++), -
.

.
,
, D
.
:
template Select(bool cond, T1, T2) {

-
.
, .
template (
Select) , (
).
, ,
, ,
.

, , ,
.
, .,
: S elect!(true, int, double).foo.
Select, :
template Select(bool cond, T1, T2) {
s t a t i c i f (cond) {
a l i a s T1 ;
} e ls e {
a l i a s T2 ;

>

342

7.
u n ittest {
a l i a s S e l e c t ! ( f a l s e , i n t , string).TypeMyType;
s t a t i c assert(is(MyType == s t r i n g ) ) ;

>
,
,
,
. ():
s t r u c t /* c la s s */ Select2(bool cond, T1, T2) {
s t a t i c i f (cond) {
a l i a s T1 ;
} else {
a l i a s T2 ;

>
}
u n ittest {
a l i a s S e l e c t 2 ! ( f a l s e , i n t , string).TypeMyType;
s t a t i c assert(is(MyType == s t r i n g ) ) ;

}
, .
, Select2 :
Select2!
!
,
.
, template,
-
. .
, , ,
( ):
template isSomeString(T) {
enum bool value = is(T : c o n s t(c h a r [ ]) )
| | is(T : const(w ch ar[])) | | is(T : c o n s t(d c h a r[]));

}
u n ittest {
/ /
s t a t i c as se rt(!isS o m e S tr in g ! ( i n t ) .v a l u e ) ;
s t a t i c a s s e r t ( ! isSomeSt r in g ! ( b y te [ ] ) .v a lu e ) ;
/ /
s t a t i c a s se rt(is S o m e S tr in g ! (c h a r [] ).v a lu e ) ;
s t a t i c a s s e r t( isS o m e S trin g !(d c h a r[]).v a lu e );
s t a t i c a s s e r t( is S o m e S tr in g ! (s trin g ) .v a lu e );
s t a t i c as se rt(isS o m e S trin g !(w strin g ).v a lu e );
s t a t i c a s se rt(isS o m e S tr in g ! (d s trin g ) .v a lu e );

7.5. ( template)

343

s t a t i c as se rt(isS o m e S trin g !(c h a r[4 ]).v a lu e );

}
;
, :
template f a c t o r i a l ( u i n t n) {
s t a t i c i f (n <= 1)
enum ulong value = 1;
else
enum ulong value = f a c t o r i a l ! ( n - 1 ).v a lu e * n;

}
factorial
, .
, ,
(.
5.12). fa cto ria l,
factorial ,
, . template
, S elect
isSomeString.

7.5.1.
template
, , ,
.

( Select
value isSomeString).
,
, .
.Type, ,
Select!(cond, , ) .
D , ,
: template
, ,

. :
template isNumeric(T) {
enum bool isNumeric = is(T : long) | | is(T : re a l);

}
u n ittest {
s t a t i c a s se r t( is N u m e ric !( in t)) ;
s t a t i c a s s e r t ( ! isNumeric!( c h a r [ ] ) ) ;

344

7.

isNumeric! (T),
isNumeric!(T).i s
Numeric,
.
, ,
,
. ,
.
-
. :
template isNumeric(T) {
enum bool te s t1 = ls(T : long);
enum bool t e s t 2 = is(T : r e a l) ;
enum bool isNumeric = te s t1 | | te s t2 ;

}
u n lttest {
s t a t i c a s s e r t ( i s N u m e r i c ! ( i n t ) . t e s t 1 ) ; / / !
/ / bool test1!

}

: - ,
isNumeric!(int) isNumeric!(int).isNumeric.
isNumeric!(int).isNumeric.test1,
test1
, . ,
,
. ,
, .

7.5.2. this1
,
th is. :
c l a s s Parent

{
s t a t i c s t r i n g getName(this T)()

{
return T .s trin g o f;

}
}

1
, ,
. - . ..

7.6. mixin tem plate

345

c la ssD e riv e d 1 : rent <}


c l a s s Derived2: Parent{}
unittest

{
assert(Parent.getN am e() == "Parent");
assert(Derived1.getName() == ''Derived1");
assert(Derived2.getName() == ''Derived2'');

>
th is T getName
T typeof(this).

, ,
.
Parent.getName(this T)(): Parent.getName(), Derived1.getName() Derived2.getName().
th is ,
(.
8).

7.6.
mixin tem plate

( )
.
, [27]
.

, ,

. ,
, .
- mixin template ( mixin).
, .
, mixin
AST-.
mixin ,
(), . mixin,
:
mixin template InjectX () {
p riv a te i n t x;
i n t getX() { return x; }
void se tX (int ) {

346

7.
/ /
x = ;

}
>
mixin, :
/ /
mixin InjectX;
class {
/ /
mixin InjectX;

}
void fun() {
/ /
mixin InjectX;
setX(10);
a s se rt(g e tX () == 10);

}

, fun -
InjectX . ,
getX setX,
. mixin template.
, - , InjectX
, ,
, - :
mixin template InjectX(T) {
p r iv a te T x;
T getX() { return x; }
void setX(T ) {
.. / /
x = ;

>
}
InjectX :
mixin In jec tX !i n t ;
mixin InjectX!double;

:
,
getX? ,
. , D
mixin:

7.6. mixin tem plate

347

mixin InjectX ! int MyInt;


mixin InjectX! double MyDouble;
,
mixin,
:
MyInt.setX(5);
assert(M yInt. getX() == 5);
MyDouble.setX(5.5);
assert(MyDouble.getX() == 5.5);

, mixin ;
,
, .

7.6.1. mixin
mixin
( , 7.5),
, - .
:
. :
, , ,
, .
mixin, , ,
, mixin
, .
, ,
,
:
import s t d .s td i o ;
s tr in g lookMeUp = " ";

template TestT() {
s tr in g g e t() { return lookMeUp; }

}
mixin template TestM() {
s tr in g g e t() { return lookMeUp; }
>
void main() {
s tr in g lookMeUp = " ";
alias TestT!() asTemplate;
mixin TestM!() asMixin;
w riteln(asT em plate.get());
w rite ln (a sM ix in .g e t());

348

7.

mixin
,
. mixin
;
,
.

7.7.

. , , - .
. ,
- .
- ,
.
,
. ,
,
.
a lia s - ,
. -
,
, .
, templa
te,
, .

, .
, ,
mixin,
. mixin
AST-.

.
,
, ,
(. 6.4.2)
(. 6.14).
- const
( ++). T,
: T
, .
. const
,
. ,
/ /
i n t p r in tf ( c o n s t char - format, . );

, printf
, format.
,
, .

, , .
D :

const .
, const,
.
:
printf format,
- .

350

8.

immutable , -
. , immutable,

. ,
const.

shared .

. const immutable
. , immutable
,
const
- .
immutable shared .
shared
13.
const immutable.

8.1. immutable
immutable :
,
.
.
: <>{T), -
> - immutable, const shared. ,
:

i n m u t a b le ( ln t ) forever = 42;
- forever
. , immutable(int) , (
int). , :

a l i a s lm m u ta b le (in t) S tab le In t;
S ta b le In t forever = 42;

forever auto,
immutable(int) ,
. ,
,
s ta tic (. 5.2.5) ref (. 5.2.1).

u n itte st {
i n m u t a b le ( in t ) forever = 42;
a u to andEver = forever;
++andEver; / / ! !
>

8.1. immutable

351

immutable
, :
void f u n (int x) {
immutable(int) xEntry = x;
}
immutable
, fun.
, xEntry
x .
immutable
, immutable
auto:
immutable pi = 3.14, val = 42;
pi immutable(double), val immutable(in t).

8.1.1.
immutable. :
struct Point { int x, ; }
auto origin = immutable(Point)(0, 0);
T , immutable(T) -
, , immutable(Point)(0, 0)
- Point(0, 0).

. ,
origin ,
origin.xH origin.y.
, immutable .
unittest {
auto anotherOrigin = immutable(P o in t ) ( 1, 1);
origin = anotherOrigin; / / !
o r ig in .x = 1;
/ / !
o r ig in .y = 1;
/ / !

I
, immutable
Point,
, . , :
static assert(is(typeof(origin.x) == immutable(int))); / /
. ,
, :

352

8.
s t r u c t DataSample {
i n t id;
double[] payload;

>
, immutable(DataSample)
. payload?
u n ittest {
auto ds = immutable(DataSample)(5, [ 1.0, 2.0 ]);
ds.payload[1] = 4.5; / / ?

}
,
. ,
, immutable, Data
Sample, ,
, 1.
- ,
: ,
, .
D .
.
,
, (
, ). , ,
. . D
:

.
-,
, - .
-
.

, -

.

. -
, ,
. -
:
, .
,
, ;

1 const ++.

8.2. immutable

353

,
,
,
.
immutable(T), ,
, ,
immutable, . ,
,
immutable, .
, , ,
.

8.2. immutable
, ,
,
- , , ,
immutable ,
. , ,
:
a l i a s imm utable(lnt[]) T1;
a l i a s im m utable(int)[] T2;


; int,
. immutable
, ,
T1 :
a l i a s immutable i n t [ ] T1;

T1 :
i n t . .

(, , ,
), - :
T1 = [ 1,
T1 b = [ 2,
= b;
a[0] = b[1];

3, 5 ];
4 ];
/ / !
/ / !

,
, , immutable(int) -
. immutable(int)[] -
, .
. ,
( ) :

354

8.
T2 = [1, 3, 5 ];
T2 b = [2, 4 ];
= b;
/ /
a[0] = b[1]; / / !
^= b;
/ / ( !)

,
. ? ,
, . (
,
, .)
(. 4 .5 ), string -
immutable(char)[]. ,
strin g,
, - immutable.
immutable -
. , Container!T. immutable(Container!T)
, Container!(immutable(T)) .

8.3.
immutable .
:
s t r i n g p r o c e s s (s trin g input);


immutable(char)[] process(immutable(char)[] input);

process ,
input, process
, , :
s t r i n g s1 = "";
s t r i n g s2 = process(s1);
a s s e r t( s 1 == ""); / /

, process ,
:
, s2.
immutable .
.
this:
class {
l n t [ ] fun();
/ /
i n t [ ] gun() immutable; / / ,

8.3.

355

immutable i n t [ ] hun(); / / To ,

}
: ,
immutable in t[],
th is. ,
immutable in t[], - :
immutable im m utable(int[]) iun();

immutable
:
imm utable(int[]) iun() immutable;

immutable

( fin a l sta tic ).
, ,
:
c la ss {
immutable {
i n t foo();
i n t [ ] bar();
void baz();

}
}
, im mutable :
c la s s {
immutable:
i n t foo();
i n t [ ] b ar();
void baz();

)
,
:
c la s s {
void fun()
void gun() immutable {)

\
u n ittest {
auto c1 =
auto c2 =
c1 .fun();
c2.gun();

new ;
new immutable(C);
/ /
/ /
/ /

356

8.

8.4.
,
- . ,
: 1)
, 2) . D
.

.
, ( th is
) .
,
.
,
th is . (
, , -
, .)
, ;
,
.
, . :
class {
i n t ;
l n t [ ] b;
t h l s ( ) immutable {
= 5;
b = [ 1, 2, 3 ];
/ / fun()

}
void fun() immutable {

}
}
super
,
. .
.
,
, :
c l a s s L ist {
p r iv a te i n t payload;
p r iv a te L ist next;
t h i s ( i n t [ ] data) immutable {
e n f o r c e (d a ta .le n g th );
payload = data[0 ];

357

8.5. immutable
i f ( d a ta .le n g th == 1) return;
next = new im m utable(L ist)(d ata[l

$]);

}
>
,
.
,
, .
1.

8.5. immutable
:
u n ittest {
i n t = 42;
immutable(int) b = ;
i n t = b;

}
.
: int immutable(int),
immutable(int) int. ,
. , int in t[],
:
i n t [ ] = [ 42 ];
imm utable(int[]) b = ; / / !
i n t [ ] = b;
/ / !

,
,
.


. T
immutable(T), T .
,
T .
:

, in t,
;

,
, ,
;

1 -.

358

8.

, ,
, ;

, ,
.

, S1 , S2 - :
s t r u c t S1 {
i n t ;
double[3] b;
s t r i n g ;

}
s t r u c t S2 {
i n t x;
f l o a t [ ] ;

}
- S2.y S2 ,
immutable(S2) <^ S2 .
,
, , ,
immutable.
, . int
,
int immutable(int) .
,
, .
,
. ,

std.conv.to1,
.
import std.conv;
stru ct S {
p r iv a te i n t [ ] ;
/ /
this(im mutable(S) source) {
/ / -immutable
= to !(in t[])(so u rce.a);

}
/ /
th i s ( S source) immutable {

1 , T[], const(T)[] immutable(T)[]


dup, T[], idup,
immutable(T)[]. - . . .

8.6. ^

359

/ / immutable
= to !(im m u ta b le (in t[] )) ( s o u rc e .a ) ;

}
>
u n ittest {
S ;
auto b = immutable(S)(a);
auto = S(b);

>
, .

8.6. const
immutable,
, ,
. ,
, immutable
. - , :
,
.
( immutable), immutable
: , ? .
, :
, - - . ,
: , . ,
.
- ,
print, - . print
,
immutable:
void p rin t(im m u tab le (in t[]) data) {
}
u n ittest {
imm utable(int[]) myData = [ 10, 20 ];
print(myData); / /

}
. , in t[],
.
, in t[]
immutable(int)[] - ,
. ,
print in t[].
, print
,
, .

360

8.

, ,
. print :
void 1(___[]) data) {

, ___
, const.
:
const(T), , .
, const(T)
T, immutable(T). const

.
1:
void p r i n t ( c o n s t ( i n t [ ] ) d ata) {
}
u n ittest {
immutable(int[]) myData = [ 10, 20 ];
p r i n t (myData); / /
in t[] myMutableData = [ 32, 42 ];
print(myMutableData); / /

}
, ,
const, , ,
. ,
: const(T) - T, immutable(T)
(. 8.1).

. 8.1. T: const(T) - cynepmun T, imutable(T).


, . const(T),
, T
const
, immutable.
const, immutable,
: const .

1 void print(in
i n t [ ] d ata);, ,
. - . . .

8.7. const immutable

361

, const,
, ,
, . :
c la ss (
void gun() const {}

}
u n ittest {
auto c1 =
auto c2 =
auto =
c1.gun();
c2.gun();
c3.gun();

new ;
new lmmutable(C);
new const(C);
/ /
/ /
/ /

8.7. const immutable


,
. :
struct {
c o n s t ( i n t [ ] ) ;
immutable(i n t [ ]) i;

}
u n ittest {
const(A) ca;
immutable(A) ia;

}
c a.i ia.c?
, const(immutable(int[])) immutabl e( c on s t( i nt [])) ; , - ,
ca.c i a . i ,
!
D
. ,
. const(immutable(T)),
immutable(const(T)) immutable(T),
. ; , const(immutable(T)[])
immutable(T), const(immutable(T)).
.

362

8.

8.8.

++ const
: , ,
-
, .
- s t r ch r ,
:
char* s tr c h r ( c o n s t char* input, i n t );

:
input - , , ,
, , input,
, s tr chr ,
. ++
, strchr:
char* strc h r(c h a r* input, i n t );
const char* s tr c h r ( c o n s t char* input, i n t );

, ,
++ , :
, ,
.
D
: inout. inout strchr
:
inout(char)* s tr c h r ( in o u t( c h a r) * input, i n t );

( , D
, .) , inout
immutable, const (

). strchr, ,

.
,
:
class X {

>

class Y {
p r iv a te Y _another;
inout(Y) ano ther() inout (
enforce(_another ! i s n u ll) ;

363

8.9.
return _another;

>
)
another .
, , inout
,
.
inout , ,
.

8.9.
,
.
immutable,
:
, .
.

.
immutable :
,
, - .
const,
: const ,
.
, ,
,
inout.
inout immutable, const
.

-
,
,
. () ,
( D) ,
, , .
- ,
.
,
,
. (throwing) -
1,
. ,
, ,
.
,
,
.
.

9.1.

D .
throw (. 3.11),
1 . - . .

9.1.

365

. ,
t r y (. 3.11),
catch. ,
, 1024 . :
import s t d . s t d i o ;
void m a i n ( ) {
try {
auto x = f u n ( ) ;
} catch ( E x c e p t i o n e ) {
writeln(e);

}
>
in t fun() {
return g u n ( ) * 2;

}
in t gun() {
throw new Exception("BepHeMCfl mai n") ;

>
i nt , gun
, Exception.
,
. (
,
, )
, catch.
throw fun
, .
,
,
- ,
(gun)
, ( catch
main). ,
,
; fun
gun main.
,
-
: , -
. , , ,

,
. D -

366

9.

,
. .

9.2.
D (. 9.1). throw
- , -
Throwable.
Exception,
Throwable. ,
, .
- Throwable, Exception ( AssertError; .
10) ,
, ,
. ( ,
, , . 9.4.)

. 9.1. - Exception,
catch(Exception). -
Throwable.
Exception Exception.


t r y catch, :
t ry {
} catch (SomeException e) {
) catch (SomeOtherException e) {

367

9.2.


, :
catch,
, catch
. ,
:
import s t d . s t d i o ;
c la s s MyException : Exception {
t h i s ( s t r i n g s) { super(s); }

}
void f u n (in t x) {
i f (x == 1) <
throw new MyException("");
} e ls e {
throw new StdioException("");

}
}
void main() {
foreach ( i; 1
3) {
try {
f u n (i);
} catch (StdioException e) {
w riteln("S tdioE xception");
} catch (Exception e) {
w riteln("Exception");

}
}
}
:
E x cep tio n
S td io E x c ep tio n

fun MyException.
catch- ,
catch,
MyException Exception.
, throw,
catch-.

, :
import s t d . s t d i o ;
c la s s MyException : Exception {
t h i s ( s t r i n g s) { su pe r(s); }

368

9.
void f u n ( in t x) {
i f (x == 1) {
throw new MyException("");
} e l s e i f (x == 2) {
throw new StdioException("");
} e ls e {
throw new Exception( "');

}
}
void fun D riv e r(in t x) {
try {
fun(x);

>
catch (MyException e) {
writeln("MyException'');

>
}
u n ittest {
foreach ( i; 1
4) {
try {
funD riv er(i);
} catch (StdioException e) {
w riteln("Std io E xception");
} catch (Exception e) {
w rite ln ( flp0C T 0 Exception");

>
}
>
:
M y E x c e p t io n
S td io E x c ep tio n
E x c e p t i o n


, .
.
catch E1 catch
E2 E2 E1, E2
.
. :
import s t d . s t d i o ;
void fun() {
try {

369

9.3. finally

} catch (Exception e) {
} catch (StdioException e) {
/ / !
/ / catch!

}
}
,
.
catch-
. ,
.

9.3. finally
try fin a lly ,
: ,
. ,
fin a lly try, ,
, ,
return
break. :
import s t d .s td i o ;
s tr in g fu n (in t x) {
s tr in g re su lt;
try {
i f (x == 1) {
throw new Except i on( ' HeKOTOpoe ");

}
r e s u lt = " ";
return re su lt;
} catch (Exception e) {
i f (x == 2) throw e;
r e su lt = " : " ^ e .to S tr in g ;
return re su lt;
} fin ally {
writeln("Buxofl fun");

}
}
fun
, - ,
: fun.

370

9.

9.4. ,
(nothrow), Throwable
nothrow ,
:
nothrow i n t iDontThrow(int , i n t b) {
return / b;

>
, ,
5.11.2. : nothrow ,
Exception. -
Throwable.
, Throwable
,
,
,
. nothrow
,
, .
Throwable.
Throwable: Throwable .
catch,
, ,
fin a lly - . ,

, .
D
.
,
, .
Throwable
. , , -

, ,
, , ,
.

9.5.
.
:
import std.conv;
c l a s s MyException : Exception {

371

9.5.
t hi s (s t ri ng s) { super(s); }

}
void fun() {
try {
throw new Exception("n0p0MfleH0 fun");
} finally {
gun(100);

>
>
void gun(int x) {
try {
throw new MyExcepti 0 n(text("n 0 p0 *meH0 gun #''
} f i na l l y {
i f (x > 1) <
gun(x - 1);

x));

}
}
}
, fun?
. -, fun ,
fin a lly
, gun(100)
, fun Exception. , gun(100)
MyException " gun #100".
,
, .
gun fin a lly
- 100 .
.

:

,
;

,
.


,
. ,
, .
D . Throwable
Throwable.

372

9.

Throwable.next.
() , Throwable.next
null. ,
.
.
Throwable:
class Throwable {
t h l s ( s t r i n g s);
override s t r i n g to S tr in g ( ) ;
property Throwable next();

}

. ,
, ,
. , .

, .
, :
unittest {
try {
fun();

} catch (Exception e) {
writeln("flepBM4Hoe :

'' typeid(e), "

Throwable secondary;
while ((secondary = secondary.next) !is null) {
wr i t e l n ( " BTo p n4 Ho e : " typeid(e), "

e);

e) ;

}
>
}
:
: E x c e p t i o n
fun
: M y E x c e p t io n
gu n #10 0
: M y E x c e p t io n
g u n #99
: M y E x c e p t io n
g u n #1

,

. throw
( ),
.

9.6. ,

373

D
scope.
, .

9.6. ,

,

, .
. , .

(stack u nw in din g) -
. ,
, :

-
;

fin a lly ;

scope(exit) scope(failure),
.

-
. ,
, .
/
,
, .
,
.
7.1.3.6,
File std .stdio. File
,
File .
File ;
; , ,
.
++. (
RAII, . 6.16.) , .
-
. / ,
. , HTML-
(, <b>) (</b>).
, ,

374

9.

HTML-. :
void sendHTML(Connection conn) {
conn.send(''<html>");
/ /
conn.send("</html>");

}
conn.send
sendHTML,
HTML-.
return,
sendHTML, return ,
. ,
, , sendHTML
( ). - sendHTML
. ,
,
sendHTML ,
.
- RAII (
): ,
. .
, ,
.
- finally:
void sendHTML(Connection conn) {
try {
conn. send( ''<html>");
} fin ally <
corm.send("</html>");

}
>
- ,
. fin a lly ,
try/fin ally. ,
<body>.
try /fin a lly :
void sendHTML(Connection conn) {
try {
conn.send("<html>");
/ /
try {
conn.send "<body>"):
/ /

9.6. ,

375

} fin ally {
conn. send( "</body>");

}
} fin ally {
conn.send( "</html>" );


fin a lly ,
, :
void sendHTML(Connection conn) {
i n t step = 0;
try {
conn, sencf("<html>");

/ /
step = 1;
conn.send("<body>");
. . . / /
step = 2;
} fin ally |
i f (step > 1) conn.send('</body>");
i f (step > 0) conn.send("</html>");

}
}
,
,
.

scope. -
scope. , ,
,
.
void sendHTML(Connection conn) <
conn.send("<html>");
sco pe(ex it) conn.send("</html>");
.. / /
conn.send(''<body>");
sc o p e ( e x it) conn. send("</body>");
/ /

>

. -, ,
.
/. -,
sendHTML
,

376

9.

. -,
, .
-, ,
scope .

9.7.
,

.
, main,
, s ta tic th is.
, Throwable
. , ,
Throwable - ,
.
; ,
, , .

10

,
, ,
.
, (
, ,
).

, .
, -
, :

( 9)
,
.


(, - )
. (
.)

-
, ,
,
. - ,
(

- [59]).

.


, -

378

10.

(,
), - ,
(,
,
0 100,
Date).
, , ,
, ,
, assert.
-
, [45],
[40] Eiffel.

.

,
,
.
, ,
[24] [61].
D ,
,
.

10.1.

,
. :
( )
, ,
,
.

(
) ().
, ,
.
/
.
:

(a ssertio n ) -
: ,
if. ,
assert .

10.1.

379

assert AssertError.
AssertError :
Exception, Error,
AssertError .

p r e c o n d itio n ) - ,
, .
(,
) (,
).
p o stco n d itio n ) -

.
(in v a ria n t) ,
. D
.


, .
, - .
std.math :
double sqrt(double x);
:
double,
double. sqrt("hello")
sqrt . ,
sqrt(2), 2 in t, double:
,
2 double
, .
, ,
pure:
/ /

pure double sqrt(double x);


,
sqrt, sqrt .
, nothrow (
) :
/ / ,
/ / ( std.math)

pure nothrow double sqrt(double x);


,
double, ,
. . ,
, .

380

10.

,
. ,
( K&R
) :
K&R ,
:
/ / s q r t, ,
/ / , ,
/ /
int s q r t ( . );

,
#include math.h (
sqrt),
sqrt("hello"). (
, .)
, sqrt(2),
math.h ,
. #include sqrt
2 2.0,
: 2, sqrt
,
, 32- IEEE 2.8026e-45.
,
.

. ,
.
? , , ( ,
):
.

, , , ,
.
, ,
. ,
,
( ).
:
, .
.

381

10.2.

10.2.
assert 2.3.4.1,
,
. ,

.
, assert -
: ()
:
int , b;
assert(a == b);
assert(a == b, " b ");
,
,
if: , , .
, assert
AssertError; .
AssertError,
.
, ,

:
import std.conv;
void fun() {
int , b;
assert(a == b);
assert(a == b, text(a, "

b, " '));

}
std.conv.text
. , :
, . .

assert, ,
.
assert ?
( ) -
. D
assert .
; AssertError, Error
, 9.2.

382

10.

AssertError, assert,
catch(Exception), .
,
, ,

.
AssertError,
catch Exception ,
Error AssertError. : -
Error.

10.3.
- ,
. ,
fun
. , fun
. D :
double fu n (d o u b le x)

ln <
a s s e r t ( x >= 0 ) ;

>
body {
/ / fun

}
in . :
double fun(double x) {
a s s e r t ( x >= 0 ) ;
/ / fun

}
, ,
.

,
, :
/ / D
double fun(double x)
i n ( x >= 0 )
body {

10.3.

383

D - ,
. ,
,
AssertError. , fun ,
:
import std.conv, std.exception;
c l a s s CustomException : Exception {
p riv a te s t r i n g origin;
p riv a te double val;
t h i s ( s t r i n g msg, s tr in g orig in , double v al) {
super(msg);
t h i s . o r i g i n = origin;
t h i s . v a l = val;

}
override s tr in g to S tr in g () {
return t e x t( o r ig i n , ":
s u p e r .to S tr i n g ( ) , v a l);

>
}
double fun(double x)
in {
i f ( x !>= 0) {
throw new CustomException(
" "
"fun" x);

}
>
body {
double y;
/ / fun
return y;

}
. ,
assert AssertError,
.
AssertError
Error, Exception,

, .
,
, . -, in return, ,

. -, D
. , :

384

10.
dou ble f u n (d o u b le x)
in {
i f (x <= 0 ) x = 0; / / !
/ / x !

>
body {
dou ble ;
retu rn ;

>

( ), .
-
. :
,
.
,
, - .

10.4.
in-, fun
: ,
.
, fun ?
out-. , fun ,
0 1:
dou ble fu n (d o u b le x)
/ /
in {
a s s e r t ( x >= 0);

}
/ /
ou t(resu lt) {
a s s e r t ( r e s u l t >= 0 && r e s u l t <= 1);

}
body (
/ / fun
dou ble ;
retu rn ;

}
in- , out
. ,
.
result, out, ,
. result ;

10.5.

385

out{...} - out-,
void.
result .
in-, out- , .
out-
( )
( ). , out-
.
out.
: out-
result, (, )
:
I n t f u n (in t x)
o u t( r e s u l t ) {
x = 42;
/ / !
/ / x !
i f ( r e s u l t < 0) r e s u lt = 0; / / !
/ / !

}
body {

10.5.
- ,
. , ,

. ,
, .

, D. , ,
Date, ,
:
c la s s Date {
p riv ate u in t year, month, day;

>
,
Date day, month year
. :
import std.algorithm , std.range;
class Date {
private:

386

10.
u in t year, month, day;
i n v a r i a n t( ) {
a s s e r t( 1 <= month && month <= 12);
switch (day) {
case 29:
assert(month != 2 | | leapYear(year));
break;
case 30:
assert(month != 2);
break;
case 31:
assert(longMonth(month));
break;
d e fa u lt:
a s s e r t( 1 <= day && day <= 28);
break;

>
/ /

}
/ /
s t a t i c pure bool leapY ear(uint ) {
return ( % 4) == 0 && ( % 100 | | ( % 400) == 0);

}
s t a t i c pure bool longMonth(uint m) {
return ! (m & 1) == (m > 7);

>
public;

}
29, 30 31
.
longMonth true, 31 ,

, , (
1, 3, 5, 7, 8, 10 12).
,
Date.
. , ,
,
, .
Date :
/ / Date
void copy(Date another) {
year = another.year;
_c a l l _ i n v a r i a n t ( ) ; / /
month = another.month;
_c a l l _ i n v a r i a n t ( ) ; / /
day = another.day;

387

10.5.
__c a l l _ i n v a r i a n t ( ) ;

/ /

>
, - Date
,
- . (
, , 29
2012 ., 1 2015 .
29 2015, .)

? . ,
. , ,
.
, , 31
30 .
/ / Date
nextMonth() {
__c a l l _ i n v a r i a n t ( ) ;
s c o p e (e x it) __c a l l _ i n v a r i a n t ( ) ;
i f (month == 12) {
++;
month = 1;

void

/ /
/ /

} e ls e {
++month;
ad ju stD a y ();

}
>
/ /
p r iv a te vo id a d ju stD a y () {
__c a l l _ i n v a r i a n t ( ) ;

/ /

/ / ()

s c o p e (e x lt)

__c a l l _ i n v a r i a n t ( ) ;

/ /

/ / ()

sw itch (day) {
c ase 29:
i f (month == 2 && ! l e a p Y e a r ( y e a r ) ) day = 28;
break;
case 30:
i f (month == 2) day = 28 + l e a p Y e a r ( y e a r ) ;
break;
c a se 3 1 :
i f (month == 2) day = 28 + l e a p Y e a r (y e a r ) ;
e ls e i f (!isLongMonth(month)) day = 30;
break;
d e fa u lt:
/ /

break;
}
}

388

10.

nextMonth
(private) adjustDay,
. - : adj ustDay
! , - adjustDay
Date!
adjustDay ? :
() , ,
Date.

. ,
: ,
.
(protected) ?
6.7.6 protected
public. ,
- .
,
:
1. .
2. .
3. .
, ,
, Date. :
class Date {
private uint day, month, year;
invariant() { ... }
this(uint day, uint month, uint year) {
scope(exit) _call_invariant();
}
^this() {
_call_invariant();
>
void somePublicMethod() {
_call_invariant();
scope(exit) _call_invariant();
}
}
. ,
6.3:
. ,
,
, .

10.6. .

389

10.6. .


. (
) , ,
, .

, .
D (-release
),
,
,
.
( ), .
, ,
,
.
- ,
,
.
,
. :
. ,
, assert, in out
. :
, , - -
.
-
, assert(++x < ),
. :
,
.

10.6.1. enforce - () assert


, assert
.

i f (!expr1) throw new SomeException;


i f (!expr2) throw new SomeException;
i f (!expr3) throw new SomeException;

390

10.
a s s e r t( e x p r 1 );
a s s e r t( e x p r 2 );
a s s e r t( e x p r 3 );

assert
assert - ,

, - .
- VERIFY, ASSERT_ALWAYS ENFORCE.
D enforce std.exception.
enforce , assert:
en fo rce (e x p r1 );
enforce(expr2, " ");

- - , enforce
Exception ,
.
:
import std .exception;
bool something = true;
enforce(something, new ('- "));

something , ,
; enforce
1, something ,
.
assert enforce
, .
:

a ssert , enforce -
,
;

a ssert AssertError,
, enforce
, (

);

a ssert , ,
,
; enforce , enforce(e)
, e .

1 5.2.4. - . . .

10.6. .

391

10.6.2. assert(false) -
, ,
( a sser t(fa lse), assert(0) assert(n ull))
, .
assert(false);
: AssertError.
assert(false);
; .
,
, assert(fa lse).
. Intel HLT ( h alt !), .
,
, - .
, , ,
- , .
assert(fa lse) -
. ,
HLT ,
assert, .
a ssert(fa lse)?
. HLT,aassert(false) .
, a sser t(fa lse),
a sser t(fa lse) :
i n t fu n (in t x) <
++x;
assert(fa lse );
return x; / / !
/ / !

}
, , a ssert(fa lse)
. , ,
std.exception.enforce(false):
import std.exception;
str in g fun() {
en fo rce (fals e, " "); / /
assert(false);
/ /

}
enforce(false) ,
. assert(false); ,
. fun

392

10.

return "";, -
enforce, fun . asse r t(fa lse ) - deu s ex m achina,
.

10.7. -
,
. :
:
?

.
readText,
. ,
:
import std .file , std.utf;
string readText(in char[] filename)
out(result) {
std.utf.validate(result);
}
body {
return cast(string) read(filename);
}
( , readText - ;
s td .file .)
readText
. -, , readText
read. void[]; read
Text cast.
:
UTF-? , out-
readText std .u tf.validate, UtfException,
UTF-.
, :
,
. ,
, . ,
D ,
.
, ,
,

10.7. -

393

.
, ,
, . - ,
,
! . ,
,
,
. readText,
:
im portstd.file, std.utf;
string readText(in char[] filename) {
auto result = cast(string) read(filename);
std. u tf.validate(result);
return result;
}

: ,
;
.
,
, ,
?
, M icrosoft W indow s A PI D esktop
Environm ent. A PI ,
,
. ( , A PI

.)
, ? , ,
,
,
, , .
, , ,
( Xyz
), , .
A PI
- .
- .
-
: ,
.

? .
.

394

10.

.
- ,
.
,
.

,
.

10.8.
[38] ,
- :
() ,
(). , ,
.

:
-
,


. ,
. -
,
. ,
: ,
.

10.8.1.
Date. ,
, BasicDate,
,
-. BasicDate format,
string ( )
, :
import std.conv;

class BasicDate {
p r iv a te u in t day, month, year;
s t r i n g fo rm a t(strin g spec)
in {
/ / spec "%Y/%m/%d"
a s s e r t( s p e c == "%Y/%m/%d");

395

10.8.

}
body {
/ /
return te x t( y e a r , / ' month,

/ ' , day);

}
}
, Date.format, ,
"%Y/%m/%d",
, , ,
, . ,
BasicDate. - ,
, .
BasicDate Date
, , %Y, %m %d
.
, %%,
%.
.
, Date :
import std.regex;
c la ss Date : BasicDate {
override s t r i n g fo rm a t(strin g spec)
in {
auto p a tte rn = regex("~(%[mdY%]|[ %])*$");
a s s e r t ( !match(spec, pattern).em pty);

}
body {
str in g r e s u lt;
return re su lt;

}
}
Date spec
. -
:
[26] ,
. , ,
"~(%[mdY%] |[^%])*S' : ,
: %, m, d, Y % ,
%. ,
, .
,
, , . (

396

10.

D -
std. regex.)
Date.format?
BasicDate.format, .
, in- ,
. , Date.format
BasicDa
te.format. :
- ,
;
- ,
.
, in-
:
, . ,
,
, . ,
, .
Date BasicDate.
''%Y/%m/%d"
.
-.
.
, , :
void __in_contract_Date_form at(string spec) {
try {
/ /
th is .B a s ic D a te ._in_contract_form at(spec);
} catch (Throwable) {
/ / ,
t h i s . D ate._in_contract_form at(spec);

>
/ / ,

10.8.2.
out- .
,
. , out- ,
( in-).
, , -
, . ,
/ /, BasicDate.format

397

10.8.

- .
B a s ic D a te .fo rm a t
- , ,
:
im port s td .r a n g e , s t d . s t r i n g ;
c la s s B asicD ate {
p r iv a te u in t day, month, y e ar;
s tr in g f o r m a t(s trin g sp ec)
o u t ( r e s u lt ) {
a s s e r t( ! r e s u lt.e m p ty | | sp ec.em p ty );
}

body {
re tu rn s td .s trin g .fo rm a t(" % 0 4 s /% 0 2 s /% 0 2 s "

y e a r, month, day);

}
)

D ate :
,
:
im p o r ts td .a lg o r ith m , s td .re g e x ;
c la s s Date : B asicD ate {
o v e rrid e s t r i n g f o r m a t( s tr in g spec)
o u t ( r e s u lt ) {
bool e sc ap in g ;
s iz e _ t expectedL eng th;
fo rea c h (c; sp e c ) {
sw itch (c ) {
c a se ' %' :
i f (e sc a p in g ) {
++expectedL ength;
e sc ap in g = f a ls e ;
} e ls e {
e sc a p in g = tr u e ;
>

break;
c a se ' Y' :
i f (e sc a p in g ) {
expectedL ength += 4;
e sc ap in g = f a ls e ;
>

break;
case ' m ' : c a se ' d ' ;
i f (e sc a p in g ) {
expectedL eng th += 2;
esc ap in g = f a ls e ;
)

398

10.
break;
d efau lt:
as s e r t( !e s c a p in g ) ;
++expectedLength;
break;

}
>
assert(w a lk L en g th (resu lt) == expectedLength);

}
body {
s t r i n g re su lt;
return re su lt;

}
}
( walkLength(result) result.length?
UTF ,
.) .
out-? : -
. , -
,
. .
, ,
:
void _out_contract_D ate_form at(string spec) {
th is .B a s ic D a te ._out_contract_format(spec);
t h i s . Date.__out_contract_format(spec);
/ /

10.8.3.
out-, ,
:
.
.
invariant ,
, invariant, ,
.

10.9.
, -
. - .
,
- . -

10.9.

399

,
.
, Stack,
6.14. :
interface Stack(T) {
eproperty bool empty():
eproperty ref T top ();
void push(T value);
void pop();
}
,
.
, , .
interface Stack(T) {
6property bool empty();
eproperty ref T to p()
in {
assert(! empty) ;
}
void push(T value)
out {
a s s e r t( v a lu e == top);

}
void pop()
in {
assert(! empty) ;
}
}

. Stack
,
.
, Stack ,
.
10.7,
Stack .

, ,
.
NV I (. 6.9.1). ,
NVI , , :
interface NVIStack(T) {
protected:
ref T topImpl();

400

10.
void pushImpl(T value);
void popImpl();
public:
property bool empty();
f i n a l 9property ref T to p() {
e n f o r c e ( !empty);
retu rn topImpl();

}
f i n a l void push(T value) {
pushImpl(value);
enforce(value == topIm pl()):

}
f i n a l void pop() {
a s s e r t ( ! empty);

popImpl();
}
}
NVIStack enforce-TecT,
, push, pop top
, .
,
-
.
NVIStack , pushImpl, popImpl
topImpl ,
.

11

, 100
, .
: ,
10000 ,
.
, - ,
.

.

.
, , ,
.
- , , .
, D
,
.

11.1.
,
.
. .
D , ,
D, .
,
- - . D
,

402

11.

,
, ,
, ,
,
- .
D .d .di.
D ,
.d ,
. d i ( D interface - D) -
. :
UTF-8, UTF-16, UTF-32.
, BOM (byte order mark -
), ( UTF-16
UTF-32) . . 11.1
, D
( [56, 2]).
. D
. ,
,
xx -
... ... ...

00 00 FE FF

UTF-32 1

FF FE 00 00

UTF-32 2

FE FF

UTF-16

FF FE

UTF-16

00 00 00 xx

UTF-32

xx 00 00 00

UTF-32

00 xx

UTF-16

xx 00

UTF-16

UTF-8

, D
,
. ,
D
, ASCII,
128.
1 - . . .
2

- . - . .

11.1.

403

D
D ( ASCII), ASCII-, ,
ASCII- /, , #,
ASCII-.
. 11.1, ,
.
, - ,
, , ,
D.
( , ) -
#!,
\n .
shebang1 , .

11.1.1. import

import:

im port s td . s td i o ; / / w riteln
,
import.
, .
(. 11.1).
, root.
widget.d ,
:

im port widget;

. 11.1.

S h e b a n g - . s harp-bang hash-bang, #! . . .

404

11.

-
( , )1.
im p o rt, n c K a T b w i d g e t.d i (caaa)widget.d ()
r o o t, w id get.d
. ,
, import
ro o t
:
import acme.gadget;
import acme.goodies.io;
import ,
.
:
import acme.gadget, acme.goodies.io;
: ,
, gadget.d,
root,
, . ,
io.d, gadget.d
:
import acme.goodies.io;

import goodies.io;
: io.d string.d,
import acme.goodies.string,
. ,
, root.
acme gadget.d , 11 goodies.io.
.
, ,
.
import (),
, D ,
D (. 2.1).
, 5th_element.d,
, 5 t h _ e le m e n t *
D. ,
input-output,

1
. - . . .

11.1.

405

D. , ,
D, ,
. :
.
-
.

11.1.2.
import,
, .

,
.
std, std.
?
, D
(roots), . ,
,
.
;
dmd -I,
, -Ic:\Programs\dmd\src\phobos W indow s- -I/usr/local/src/phobos UNLX-.
-I
.
, import p ath .to.file
path/to1 .
, file .d . ,
. ,
, -I.
;
, .
path.to ,
.

,
.
( )
,
,
.

1 / ;
, .

406

11.


, , ,
.

% dmd m a i n . d

,
. ,
, dmd
-v ( verbose - ). ,
D
, ( dmd
[18, 19, 20, 21]).

11.1.3.
, D
. ,
, . ,
- ,
. ,
. Object, ,
: ,
object.Object, object,
. , , coep oe aaw idget.d:
/ / widget.d
void fun(int x) {
}
fun
fun. , widget (,
main.d), widget.fun:
/ / main.d
import widget;
void main() {
widget.fun(10); / / , fun widget
}
,
. fun
,
widget.fun ?
, .
,
, :

11.1.

407

1. .
, .
2. .
, .
3. :
,
;
,
;

,
,
;

,
(. 5.5.2).
,
, ,
.
main.d fun , - :
/ / main.d
import widget;

void main() {
fun(10); / / , fun
/ / widget

)
io.d fun
:
/ / io .d acme/goodies

void fun(long n) {
}
main widget.d, io.d.
fun ,
-
:
/ / main.d
im portw idget, acme.goodies.io;

void main() {
fun(10); / / !
/ / fun():
/ / fun widget acme.goodies.io

408

11.
w idget.fun(10);
/ / ,
acm e.goodies.io.fun(10); / / ,

>
: .

, .

11.1.3.1.
5.5.2
,
, ,
. ,
, .
(fu n ction hijacking)
. ,

. :
- ,
, , .

.
, , ,
widget fun(int), acme.goodies.io - fun(long),
fun(10), main, widget.fun,
. ,
- . main
acme.goodies.io, fun(10), , acme.goodies.io.fun
.
widget, fun(10) widget.fun. ,
widget ,
main acme.goodies.io - .
, . ++
,
; Python,
, . ,
,

.
D .
D ,

. import
,
,
. , D , - , ,

409

11.1.

import,
, .
, , ,

,
.
, ,
.
, widget fun(int), aacme.goodies.io
fun(long), main :
im portw idget, acme.goodies.io;
void main() {
fun(10);
//
fun(10L); / /
//
fun("10"); / /

! !
,
acme.goodies.io.fun
! !

>
import widget
acme.goodies.io, ,
,
-
fun .

11.1.4. public import



. . 11.1.
main widget, widget
acme.gadget, , main,
acme.gadget .
widget, widget, main
.
, widget

. , widget
acme.goodies.io,
widget,
acme.goodies.io.
, public import:
/ / widget.d
/ / acme.goodies.io widget
public import acme.goodies.io;

public import ,
acme/goodies/io.d, ,

410

11.

widget.d () widget.donpedejiun . , public


import widget.d a lia s
io.d. ( ,
.) , io.d
print(string), main.d
:
import widget;
void main() {
pri nt ( ' ' 3f l paBCTByi T) ;
/ / , p r i n t
widget.print(''3flpaBCTByn"); / / , widget
/ / p r in t

}
main acme.goodies.io?
:
import widget;
import acme.goodies.io; / / ,
void main() {
'");

/ / .

wi dge t . p r i n t (" 3 f l p a e c T By ^ ' ) ;


/ / . . . .
acme. goodi es. i o. pri nt ("3Apa BCTBy^' ); / / .. !

}
io.d : , widget
acme.goodies.io,
. -
.
,
private import.
import.

11.1.5. static import



import (
11.1.3) .

(- .,
).
, ,

. ,
std .string
.
, (,
, DBCS - Double B yte Character Set),

11.1.

411

std .string ,
dbcs_string -
.
import dbcs_string sta tic:
import std.string;
/ / string toupper(string)
static import dbcs_string; / / string toupper(string)
void main() {
auto s1 = toupper("hello");
/ /
auto s2 = dbcs_string.toupper(''hello''); / /
}
: import std .strin g,
. s ta tic import
,
.
, s ta tic import
.
,
, .
s ta tic ,
:
static import teleport, time_travel, warp;
, ,
:
static {
import teleport;
import time_travel, warp;
}

11.1.6.

-
. :
/ / nain.d
import widget ; fun, gun;

: import - fun
gun.
widget! , widget fun,
gun hun. fun gun ,
main. ,
hun, widget.hun widget.fun, :

412

11.
/ / main.d
Import widget : fun, gun;
void main() {
fun();
gun();
hun();
w idg et.fun ();
widget.hun();

/ /
/ /
/ / !
//!
//!

>
,
, -
, , ;
, ,
.
,
, D,
.
,
, D , .

11.1.7.

. -
, , ,
,
.
,
:
import u t i l . c o n t a i n e r . f i n i t e . l i n e a r . l i s t ;


, u til.con tain er.fin ite.linear.lis t
:
import l i s t = u t i l . c o n t a i n e r . f i n i t e . l i n e a r . l i s t ;

import
list.sym bol util.contain er.fin ite.lin ear.list.sym b ol. , ,
, List, :
import l i s t = u t i l . c o n t a i n e r . f i n i t e . l i n e a r . l i s t ;
void main() {
auto ls t1 = new l i s t . L i s t ;
/ /
auto l s t 2 = new u t i l . c o n t a i n e r . f i n i t e . l i n e a r . l i s t . L i s t ; / / !
/ / u t i l !

413

11.1.
auto l s t 3 = new List;
/ / !
/ / L ist !

}

( u til, container,..., lis t ) ,
lst2
u til. ,
, , (. 11.1.5)
, ;
new List.
,
, a lia s (. 7.4):
import u t i l . c o n t a i n e r . f i n i t e . l i n e a r . l i s t ;
/ /
a l i a s u t i l . c o n t a i n e r . f i n i t e . l i n e a r . l i s t l i s t ; / /
void main()
auto lst1
auto l s t 2
auto ls t3

{
= new l i s t . L i s t ;
/ /
= new u t i l . c o n t a i n e r . f i n i t e . l i n e a r . l i s t . L i s t ; / /
= new List;
/ /

}

(. 11.1.6). :
import s t d . s t d i o : say = w riteln ;
void main() {
', !");
s t d . s t d i o . ', ");
writeln(''3flpaBCTBy^ !");
s t d . stdio.w riteln(''3flpaBCTByn, ! ");

//
//
//
//

, w rite ln
!
!
!

}
, ,
,
.
, ,
( ):
import io = s t d . s t d i o ; say = w riteln , CFile = File;


.
D ,
:
import io = s t d . s t d i o : w rite ln , File;
import s t d . s t d i o : say = w rite ln , CFile = File;

import
.

414

11.

, . ,
,
import.
io.w riteln, io .F ile, say CFile.

11.1.8.
11.1, , import
, D,
-
, ,
D.
,
, , ,
, , ,
,
. , :
D.
, ,
,
, gnome-cool-app.d. D
,
. , D
,
, gnome-cool-app .
-
-1-, , gnome_
cool_app.d. , , ,
: ,
:
module gnome_cool_app;
gnome-cool-app.d (
), ,
,
gnome_cool_app.
; :
module p a th .to .n o n e x is te n t.lo c a tio n .a p p ;
,
app.d path/to/nonexistent/location.
, :
import, ,
gnome-cool-app.d, .

415

11.1.

11.1.9.
D ,
, ( ++
).

import.
,
, , ,
.
(m odule su m m aries),
. - ,
, .
-
. ,
, .

,
-.
D. :
/*

-/
module acm e.doitall;

/**

*/
c la ss {
void fun() {
}
f i n a l void gun() {
. }

}
c la ss B(T) {
void hun() {

}
void foo() {

}
void b a r ( in t n ) ( f l o a t x) {

>
d o ita ll ,
, ; (
):

416

11.
module a c m e . d o i t a l l ;
class {
void f u n ( ) ;
f i n a l void gun();

>
c l a s s B(T) {
void hun() {

>

>
void f oo( ) ;
void b a r ( i n t n ) ( f l o a t x) {

}
, ,
acm e.doitall.
.

( dmd
-H). , ,
,
.
, .
. , acm e.doitall.foo
,
.
, ++,
( )
.
, ,
. ,

, ,
. ,
,
( ) ,
,
. ,
(, ).
D - : 1)
, 2) , 3)
.
1) - ,
. ,

11.1.

417

,
. 11.2.

. 11.2.
()
acme,
acme acme_impl
(. 11.1.2), acme
:
/ / c l i e n t . d
import acme.algebra;
import acme.io.network;

acme .
, ,
acme,
acme_impl. .
, algebra.d acme_impl,
, algebra ,
acme:
/ / acme_impl/algebra.d
module acme.algebra;

io :
/ / ac m e_ im pl/io/file.d
module acme.i o . f i l e ;

418

11.


.
, :
% dmd c l i e n t . d

/p a th /to /a cm e _ im p l/a lg eb ra .d

import clien t.d acme.di


/path/to/acme. ,
, .
clien t.d
acme,
. -
acme dmd .
;
, :
% cd /p a th /to /a cm e _ im p l
% dmd - l i b - o f a c m e a l g e b r a . d g u i . d

io /file .d

io /n e tw o r k .d

-lib , -of (
output file - ) acme.lib (Windows)
acme.a (U N IX - ).
, - :
% dmd c l i e n t . d

a c m e .lib

acme ,
, .
,
.

11.2.

,
.
, ,
[46, . 1].
D :
class { int x; }
:
flo a t[] array;
D ( , )
x
- , , array[n]

11.2.

419

n x
. ,
D -
cast union.
void mai n( ) {
f l o a t [ ] a r r a y = new float[1024];
auto obj = cast(A) a r r a y . p t r ;

>
( ,
, )
obj.x.

11.2.1.

flo a t
, ,
.
null, ,
.
- , ,
, ,
.
,
: . D
:
D
. :

:

;
( null
);
:
. ,
, .
- cast:

, , - array
obj ,
- .

( , [15].
: -

420

11.

.
, -
.
.)

. , , ,
int,
int.max.
-
.
std.math , sqrt(-1)
double.nan. ,
double.nan - ,
, sq rt.
- :
,
, N aN () (. 2).
,
s q rt .
, .

11.3.2. @safe, @trusted @system



- D,
cast.
D .
, ,
, , .
.
D
.
,
.
, ,
.
.

,
.
,
.

, ?
D -

11.2.

421

, : ,

.
, :
module my_widget;
0 sa fe :

@safe, @trusted system,


. (
; -3 ,
.)
, @safe,
D, :

(, int),
;

,
;

, , ,
,
;

( ,
,
);

,
@safe @trusted;

, const,
immutable shared;

- @system.

; ,


. D (
SafeD) -
SafeD.
, , ,
.
@system:
0system:
void * a l l o c a t e ( s i z e _ t s i z e ) ;

422

11.
void deallocate(void* p);

@system ,
- .
, ,
,
.
D. @trusted.
- ,
.

; .
dmd
@system; @safe
-safe.
SafeD -,
,
, .

11.3.
-
.
, ( ?) ,
.
/ , .
, ,
, .
(, ),
W indow s .
, ,
W indow s V ista
. ,
:
p r iv a t e enum WinVersion { preVista, v is t a , postV ista }
p r iv a te WinVersion winVersion;
sta tic th is() {
OSVERSIONINFOEX info;
info.dwOSVersionInfoSize = OSVERSIONINFOEX.sizeof;
GetVersionEx(&info) | | a s s e r t ( f a l s e ) ;
i f (info.dwMajorVersion < 6) {
winVersion = WinVersion.preVista;

11.3.

423

} else i f (info.dwMajorVersion == 6 && info.dwMinorVersion == 0) {


winVersion = WinVersion.vista;

> else {
winVersion = WinVersion.postVista;

}
}
s t a t i c t h i s ( ).
main.
.
, :
/ /

static ^this() {
}
, main
,
.

.

11.3.1.


, ( ).
- (
).

, main.
,
.
- ,
, ,
.

11.3.2.

, .

(. 6.3.6) , ,
, , -
. ,
1 2:

424

11.


1 2,
;

1 2, 2 1:
- ,
;

! 2:2 1, 2 -
!;

2 1: 1
2, 1 -
2;

1 2,2 1:

.


.
, :
, ,
, .
, ,

.

11.4.
,
. ,
.

,
.

.
,
- , , ,
. (
, )

( XM L, HTML PDF).
D ,

. ; ,

11.5. ++

425

(
),
.

. ,
;
D, -

D.

11.5. ++
D ++.
:
++, D
++. ,
D ++,
.
++,

:
extern(C) i n t foo(char*);
extern(C++) double bar(double);

,
,
(
name m angling), D
.
D ++,
:
extern(C) i n t foo(char*) {
.. / /

}
extern(C++) double bar(double) {
/ /

}

, -.

D, .

426

11.

11.5.1. ++1
, D ++ D.

. D ++,
D
++:
/ / ++
c l a s s Foo {
public:
v i r t u a l i n t method(int , i n t b) {
return + b;

}
};
Foo newFoo() {
return new Foo();

}
void deleteFoo(Foo* obj) {
d e l e te obj:

}
/ / D
extern (++) {
in te r f a c e Foo {
i n t method(int, i n t ) ;

}
Foo newFoo();
void deleteFoo(Foo);

)
void main() {
auto obj = newFoo;
s c o p e(ex it) deleteFoo(obj);
assert(obj.m ethod(2, 3) == 5);

}
, ++,
++,
++ Foo.

1 ,
,
. - . . .

11.6. deprecated

427

extern (++) void call(Foo);


/ / ++ void call(Foo* f);

extern (++) interface Foo {


int bar(int, int);

}
c la s s FooImpl : Foo {
extern (++) int bar(int , int b) {

//
}
}
void main() {
FooImpl f = new FooImpl();
call(f);

>

11.6. deprecated
(, )
deprecated. ,
.
deprecated ,
.
,
,
(-w dmd).
deprecated
A PI .
,
, ,
deprecated. ,
deprecated - , ,
.

11.7.
, ,
. , , -
- ,
. ,
D version,
.
.
, .
, :

428

11.
version = 20100501;
version = F in a lR e le a se ;

, :
version(20100501) {
/ /

}
versio n ( P r e F i n a l R e l e a s e ) {
/ /
} e l s e version ( F i n a l R e l e a s e ) {
/ /

} else {
/ /

>
,
, . version
e lse , .
, .
,
, :
version ( P r o E d it i o n ) {
. . / /

}
version = P roE d ition ; / / !

,
, :
, .
,
(, -version=123 -version=xyz dmd).
,
.
version .
version ,
. ,
# if/# elif/# else,
,
, .
version D ,
, .
, ,
, (, Win32, Posix Mac),
(LittleEndian, BigEndian) .

429

11.8.

, version(unittest).
__FILE__ __ LINE__
.
version
.

11.8.
-
. debug
,
.
debug:
module

mymodule;

void f u n () {
i n t x;
debug(mymodule) w r it e ln (" x = "

x);

}
mymodule,
^ =|^1, debug(mymodule)
true, ,
debug. debug(5),
>= 5.
debug
, .
debug . ,
, ,
-debug. version,
, .

11.9. D
D , P h o b o s 1,
.
A P I , ,
.

1 (Phobos) - . -
D (. ). Digital Mars ( ) , D -
dmd ( Digital Mars D). - . ..

430

11.

- std.
:
, ,
, , ,
,
, . std
.
, core,
std , .
std :
.
.
Phobos . 11.2.
11.2.

s t d .a l g o r it h m


, .
++ (Standard Template Library, STL).
70 ,
.
.
STL
, D - ,
;
D [3]

s t d .a r r a y

std .b ig in t

s td .b it m a n ip

s t d .c o n c u r re n c y

(. 13)

std .c o n ta in e r

s t d .c o n v

,
.
, t o t e x t

s t d .d a t e t i m e

std .file

.
; , read,
, s t d . f i l e . read
,
( s t d . s t d i o , . )

s td .fu n c tio n a l

11.10.

431

std.getopt

std.json

JS O N

std.math

std.numeric

std.path

std.random

std.range

std.regex

std.stdio

/ ,
std io .
,
, std.algorithm,

s td .strin g

, .
std .a lg o rith m , s t d . s t r i n g ,
, (
) std.algorithm ,

std .traits

std.typecons

, Tuple

std .u tf

U TF

std.variant

Variant,
. Variant -
union

11.10. 1
, ,
, ,
, ,
, D
. D -
, .
,
, -

1 ,
,
. - . ..

432

11.

1.
D,
.
D
* 8 6 jc86-64,
.

11.10.1. x86
,
asm:
asm {
naked;
mov ECX, EAX;
movEAX, [ESP+size_t.sizeof*1];
movEBX, [ESP+size_t.sizeof*2];
L1:
mov DH, [EBX + ECX - 1];
mov [EAX + ECX - 1], DH;
loop L1;

ret;
}
asm :

:
<> <apr^, - a p r^ ,

., <>;

:
>:

:
<> <apr^, *2>,

..,

<>;

.
.
.
.
.
goto
asm, jmp c a ll.
asm ,
asm. ,
D, .

, A s se m b le r . . . . ..

433

11.10.

,
asm, , (
) .
(
):
mov EDX, 5[EAX][EBX];
mov EDX, [EAX+5][EBX];
mov EDX, [ EAX+5+EBX];

,
, , asm:
int* p = a r r . p t r ;
asm

{
mov EAX, p[EBP];
//
mov EAX, p;
//
mov EAX, [p + 2 * in t. s iz e o f ] ; / /
//

EAX
.
.
EAX
.

}
, <> ptr:
add [EAX], 3;
add [EAX], i n t p tr 3;

/ / 3 ,
/ / .

ptr near, far, byte,


short, int, word, dword, qword, flo a t, double real. far ptr
D.
byte ptr. seg :
mov EAX seg p[EBP];

.
asm : $,
, __LOCAL_SIZE,
.
,

offsetof:
s t r u c t Regs

{
uint eax, ebx, ecx, edx;

}
void pushRegs(Regs* p)

<
asm {
push EAX;
mov EAX, p;

434

11.
/ / p.ebx EBX
mov [EAX+Regs.ebx.offsetof], EBX;
/ / p.ecx ECX
mov [EAX+Regs.ecx.offsetof], ECX;
/ / p.edx EOX
mov [EAX+Regs.edx.offsetof], EDX;
pop EBX;
/ / p.eax EAX
mov [EAX+Regs.eax.offsetof], EBX;

)
}
* 8 6 (
):
AL

EAX

BP EBP ES CS SS DS

BL BH

BX

EBX

SP ESP

CR0 CR2 CR3

GS FS

CL CH

CX

ECX

DI EDI

DR0 DR1 DR2 DR3 DR6 DR7

DL DH DX

EDX

SI ESI

TR3 TR4 TR5

CR4

TR6 TR7

ST
ST(0) ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7)
MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7
XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7

D :
align <_<;
_ ,
align , _,
( N ot OPeration), 0x90.
even;
even
( align 2).
,
.
naked;
naked
. , ,
, .
naked,

435

11.10.


.
D
db, ds, di, dl, df, dd, de,
byte, short, int, long, flo a t, double extended
(extended -
10 , D real).
.
n , n -
, .
,
:
asm {
naked;
db 0x89,
db 0x5c,
db 0x88,

0xc1, 0x8b, 0x44, 0x24, 0x04,


0x24, 0x08, 0x8a, 0x74, 0x0b,
0x74, 0x08, Oxff, 0xe2, 0xf6,

0x8b;
0xff;
0xc3; / / .

}
, lock, rep, repe, repne, repnz repz,
:
asm

<
rep;
movsb;

)
D pause.
:
;
;


.
fdiv
fmul
fdiv
fmul

ST(1);
ST;
ST,ST(1);
ST,ST(0);

//
//
//
//

11.10.2. x86-64
* 8 6-64 x86
.
x 8 6-64 x86.
x 8 6 -6 4 64 . :
RAX, RBX, RCX, RDX, RBP, RSI, RDI, RSP, RIP RFLAGS, RIP

436

11.

. 64-
R8, R9, R10, R11, R12, R13, R14, R15.
32
D, 16 - W, 8 - . , R8D - 4
R8, R15B - R15. XMM XMM8-XMM15.
RIP . RIP
. * 8 6 ,
, :
asm
{
call $;
pop EBX;
add EBX,

6;

mov AL, [EBX];


;

//
//
//
//
//
//


,
EBX.

pop, add mov.
AL
;

}
* 8 6 -6 4 1:
asm
{
mov AL, [RIP];
;
}

/ / ,

, RIP
jm p /jx x c a l l , RIP,
. , c a l l $;
, , ,
p u sh RIP; ( ).

.

11.10.3.
.
* 8 6 , *86-64 - , SPARC - ,

1 dmd2.052 RIP. ,
. mov AL, [RIP];
0x8A, 0x05; di 000000000;, . :
,

,
db. - . ..

11.10.

437

.
,
, .
.
dmd D_InlineAsm_X86,
xS6, D_InlineAsm_X86_64 * 8 6 -6 4 .
:
void optimizedFunction(void* a r g ) {
version(D_InlineAsm_X86) {
asm {
naked;
mov EBX, [EAX];

>
>
else
version(D_InlineAsm_X86_64) {
asm {

naked;
mov RBX, [RAX];

}
}
e ls e {
size_t s = *cast(size_t*)arg;

}
}

11.10.4.

. - ,
, -, ,
, - . ,
,
.

, . -,
, -, -. ,
. ,
.
, , :

438

11.


,
.
, ,
. ,
. ,
, ,
. ,
( , , ),
, ,
,
( ).
.

11.10.4.1. x86
x 8 6
.
.
.

cded
, ( Decla
ration).
,
, .
D extern(C).
,
. .
EAX, 4 ,
, 4 . EAX
. naked,
.
extern(C) i n t increm en t(int ) {
asm {
naked;
mov EAX, [ESP+4]; / / EAX ,
/ / ( ) ,
inc EAX;
/ / EAX
ret; / / .
/ / EAX

}
}
.

11.10.

439

pascal
D
extern(Pascal). ,
.
.

stdcall
W indow s, W inA PI.
: extern(Windows). cdecl,
.

fastcall

. - Microsoft fa s tc a ll Borland
fa stc a ll.
ECX EDX.
. EAX, EDX
ECX ,
. ,
,
. D
,

.

thiscall
++.
std c a ll. ,
, ECX.

D
D EBX, ESI, EDI, .
,

,
. (
,
_arguments. _argptr ,
_arguments. .)
,
.
th is, -
, ,
. EAX,
,

440

11.

. ref out
, lazy - .
:

bool, byte, ubyte, short, ushort, int, ulnt, 1-, 2- 4- ,


( ), - EAX;

long, ulong, 8- - EDX( ) EAX (


);

flo a t, double, real, iflo a t, idouble, ireal - ST0;

c flo a t, cdouble, c r e a l - ST1 ( ) ST0 (


);

- EDX () EAX ( );

- EAX;

- EDX ( ) EAX (
).

,
. EAX
.

11.10.4.2. x86-64
* 8 6 -6 4
. ,
-M icrosoft x64 callin g convetionWindowsAMD64 ABI convention
P osix.

M icrosoft x64 calling convention


fa stc a ll.
. 4
RCX, RDX, R8, R9. 16 ,
. 4
XMM0, XMM1, XMM2, XMM3.
. .
.
RAX, 8
. XMM0.
64 ,
, .
RAX .

AMD64 ABI convention


P osix-
,
.
RDI, RSI, RDX, RCX, R8 R9, -

11.10.

441

XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 XMM7.


64 , 256 ,
. Microsoft x64,
.
, Microsoft x64.

11.10.5.
,
.
, .
.
.

.
, , ,
,
,
i386, - AM D, - Intel Core.

1,
, ,
.
version(AMD)

{
version = i686;
version = i386;

}
else version(iC ore)

{
version = i686;
version = i386;

}
e ls e version(i686)

{
version = i386;

1 dmd2.057
, ,
gcc .

, .
, D,
, GDC (GNU D
compiler) LDC (LLVM D compiler) D,
GCC LLVM. - . . .

442

11.
void f a s tP ro c e ss()

{
version(AMD) {

//
} e l s e version(iC ore) {

//
} e ls e v ersion(i686) {

//
} e l s e v ersion(i386)

//
} else {

//
}
>
, fastProcess
! - :
?
, -
,
- ,
fastProcess? , ,
, , ,
?

,
.

12

, ,
.
,
.

.
: ,
, .
-
,
.
D :
,
- D
:
1. .
, , , i n t [ ] i n t [ s t r i n g ]
, 4 e M A r r a y ! in t H A s s o t i a t i v e A r r a y ! ( s t r i n g , i n t) .B r o x n b
, i n t [ [ ] ] .
. ,
, ,
. -, Point(5, 3), -
, ,
(3, 5)pt.
. ,
. ,
"Hello" ^ " " ^ "world ',

444

12.

: ,
, .
,
.
.
; -
,
, .
,
,
. ,
, 1 (
, ,
, , , , ...
, ).
.
,
,
.
x, z.
:
m = 3 / (1/ + 1/ + 1/z);

, ,
:
m = divide(3, add(add(divide(1, x), divide(1, y)), divide(1, z )));


, .
D .

,
,
, .
.

( ,
,
),
.
,

1 * .
, .
- .
* - . - . . .

12.1. D

445

. ,
.

12.1. D
D :
,

. .
,
, ,
. ,
, + 5 a.opBinary! "+"(5).
opBinary ,
,
.
(, , . .
)
,
, D .
scope (. 3.13). , scope ,
try,
, scope
. ,
,

. ,
.

12.2.
+ (), - (), ^ (
), * ( ), ++ ( ) - ( )
<on>

a.opUnary!'' <on>"()

.
opUnary
"<on>" - . ++
.! "++" ().
T,
T.opUnary :

446

12.
stru ct T {
SomeType opUnary(string op)();

}
, ,
.
,
(. 5.4). CheckedInt,
, ,
,
, . CheckedInt
(, CheckedInt!int, CheckedInt!long ..). CheckedInt
:
s t r u c t CheckedInt(N) i f (isI n te g r a l!N ) {
p r iv a t e N value;
r e f CheckedInt opUnary(string op)() i f (op == "++") {
enforce(value != value.max);
++value;
return t h i s ;

}
ref CheckedInt opUnary(string op)() i f (op == " - - " ) {
enforce(value != value.min);
--value;
return t h i s ;

}
}

12.2.1.
mixin
, ,
. , +, - ^
CheckedInt -
value, CheckedInt. ,
.
,
. -
mixin (. 2.3.4.2),

.
, CheckedInt.1

1
. - . . .

12.2.

447

s t r u c t CheckedInt(N) i f (isI n te g r a l!N ) {


priv ate N value;
this(N value) {
t h is .v a lu e = value;

}
CheckedInt opUnary(string op)()
i f (op == "+' | | op == "-' | | op == ''^") {
return CheckedInt(mixin(op ^ "value"));

>
ref CheckedInt opUnary(string o p )() i f (op == "++" | | op == " - - " ) {
enum lim it = op == "++'' ? N.max : N.min;
enforce(value != lim it) ;
mixin(op ^ ''v a lu e ;");
return th i s ;

>
}
, ,

. - mixin,

.
. ,
op,
; ,
mixin. D
(opAdd, opSub, opMul, ...),

.

12.2.2.

(++) ( a - )
- : , ,
.
, ,
,
, . ,

.


- .
, D .

448

12.

++ (
):
++ , ++,
a.opUnary! "++"();

++ (, arr[a++]), ( )(( x) {auto t=x; ++x; return t;})(a).

,

, .
- (. 5.6),
:
,
. -
.

12.2.3. cast

, cast(T) .
,
, .
T

cast(T )


.opCast!T()

opCast, ,
T - , .

, opCast
. ,
string int T
:
stru ct T {
s t r i n g opCast(T)() i f (is( T == s t r i n g ) ) {

)
i n t opCast(T)() i f (is( T == i n t ) ) {

}
>
.
CheckedInt,
. ,

12.2.

449

,
,
. :
, (,
CheckedInt!int long).
,
, , s ta tic i f (.
3.4):
s tr u c t CheckedInt(N) i f (is I n te g r a l!N ) {
priv ate N value;
/ /
N1 opCast(N1)() i f ( i s I n t e g r a l !N1) {
s t a t i c i f (N.min < N1.min) {
enforce(N1.min <= value);

}
s t a t i c i f (N.max > N1.max) {
enforce(N1.max >= value);

}
/ / ""
return cast(N1) value;

}
}

12.2.4.

,

? <,> : <2

cast(bo ol) ? <,> : <>


i f
i f () <> / / e l s e

i f (ca st(bool) ) <>

!
cast.
,
bool, :
s tr u c t MyArray(T) {
private T[] data;
bool opCast(T)() i f (is( T == bool)) {

450

12.

re tu r n !data.empty;
>
}

12.3.
+ (), - (), * (
), / (), %( ), &( ),
| ( ), ( ), ( ), ^ ()
in ( )
-on> b

b
,
a.opBinary!" <on> '(b)

b.opBinaryRight!" <on>"(a)


, .
, .
, , *
.
CheckedInt 12.2.
:

s t r u c t CheckedInt( N) i f ( is I n te g r a l!N ) {
p r iv a te N value;
/ /
CheckedInt opBinary(string op)(CheckedInt rhs) i f (op == "+") {
a u to r e s u l t = value + rhs.value;
e n f o r c e (r h s .v a lu e >= 0 ? r e s u lt >= value : r e s u lt < value);
re tu r n C heckedInt(resu lt);

}
/ /
CheckedInt opBinary(string op)(CheckedInt rhs) i f (op == "-") {
a u to r e s u l t = value - rhs.value;
e n f o rc e (rh s.v a lu e >= 0 ? r e s u lt <= value : r e s u lt > value);
re tu r n C heckedInt(result);

)
/ /
CheckedInt opB inary(string op)(CheckedInt rhs) i f (op == ''*") {
a u to r e s u l t = value * rhs.value;
enforce(value && r e s u lt / value == rh s.valu e | |
rhs.va lue && r e s u lt / rhs.value == value ||
r e s u l t == 0);

12.3.

451

return CheckedInt( r e s u l t );
}
/ /
CheckedInt opBinary(string op)(CheckedInt rhs)
i f (op == " / | | op == "%") {
en force (rhs.va lue != 0);
return CheckedInt(mixin("value" ^ op ' " r h s.v a lu e "));

>
/ /
CheckedInt opBinary(string op)(CheckedInt rhs)
i f (op == " " | | op == " | | op == " > " ) {
e nforce (rhs.v a lue >= 0 && rhs.value <= N .sizeof * 8);
return CheckedInt(mixin("value" ^ op ^ " r h s.v a lu e '') );

}
/ / ( , )
CheckedInt opBinary(string op)(CheckedInt rhs)
i f (op == "&" | | op == " |" | | op == ' " " ) {
return CheckedInt(mixin("value" ^ op ^ "r h s .v a lu e " ) );

}
}
( -
, Intel,
,
. - .)
.
,
. / %(
),
, .
, ,
mixin .

12.3.1.

,
, ,

.
* 5, CheckedInt! int.
, CheckedInt
opBinary CheckedInt.
* CheckedInt!int(5),
.
-
opBinary CheckedInt!W, N .

452

12.

, opBinary
,
:

s t r u c t CheckedInt( N) i f ( is I n te g r a l!N ) {
/ / ,
/ / ""
CheckedInt opB inary(string op)(N rhs) {
re tu r n opBinary!op(CheckedInt(rhs));

}
>
:
,
.

12.3.2.
opBinaryRight , ,
, , ,
5 * .
, opBinaryRight! "*''(int).
- , ,
, ,
(, , 5 * * 5),
opBinary!"*"(int), opBinaryRight!''*"(int),
, . . . ,
,
: ;
, .

, -
.
<on> b b <on> ,
,
:

s t r u c t CheckedInt(N) i f ( is I n te g r a l!N ) {
/ / ,
/ /
CheckedInt opBinaryRight(string op)(N lhs) {
re tu r n C h e ck e d In t(lh s).opBinary!o p ( th is ) ;

}
>
, , CheckedInt
. .
,
. ,
5 * , Complex!double.

12.4.

453

, Complex!double(5) * , 5
, -
,
. , , ,
.
-
-
.
.
, ,
.
s t r u c t Complex(N) i f (isF lo atingP o int!N ) {
N , im;
/ /
Complex opBinaryRight(string op)(N lhs)
i f ( op == "+" 11 op == *')

{
/ / ,
return opBinary!op(lhs);

}
/ /
Complex opBinaryRight(string op)(N lhs) i f (op == "-") {
return Complex(lhs - re, -im);

)
Complex opBinaryRight(string op)(N lh s) i f (op == " / ) {
auto norm2 = re * re + im * im;
enforce(norm2 != 0);
auto t = lhs / norm2;
return Complex(re * t , -im * t ) ;

>
}

,
op.

12.4.
( ) D
, , (.
6 .8 .3 6.8.4). , ,

opBinary, . -, == !=
, <, <=, > >=.
,
, ,

454

12.

. ,
, ,
, .

, opBinary.
== b, b
, :

, b - ,
object.opEquals(a, b). 6.8.3,
,
object .

a.opEquals(b) b.opEquals(a)
, ,
a.opEquals(b). , b
, .

a.opEquals(b) b.
opEquals(a), .

-
<, <=, > >= :
a.opCmp(b) b.opCmp(a) ,
, .() <on> 0.
a.opCmp(b) b.opCmp(a). , a.opCmp(b) <on> 0.
<on> b.opCmp(a).

opEquals, opCmp.
, opCmp ( a.opCmp(b) == 0).
, .
, ,
.

12.5.

= b, , += *= . 7 .1 .5 .1 ,
=b

a.opAssign(b)

12.5.

455


<on>- b

a.opOpAssign!"<on>"(b)


.
+= CheckedInt:
s t r u c t CheckedInt( N) i f (is I n te g r a l!N ) {
priv ate N value;
ref CheckedInt opOpAssign(string op)(CheckedInt rhs)
i f (op == "+") {
auto r e su lt = value + rhs.value;
enforce(rhs.value >= 0 ? r e s u lt >= value : r e s u lt <= value);
value = resu lt;
return th is ;

}
}
. -, opAs
sign ,
CheckedInt . , , ,
. ,
. ,
enforce ,
. -,
opBinary! "+", .
,
,
. :
s t r u c t CheckedInt(N) i f (is I n te g r a l!N ) {
/ / ,
/ /
ref CheckedInt opOpAssign(string op)(CheckedInt rhs) {
value = opBinary!op(rhs).value;
return th is ;

}
>
-:
, .
;

, .

456

12.

12.6.
D - ,
, ,
.
-
. ,
.
,
= ,
+=.
,

a[b,, 2,

., b J

a.opIndex(b,, b2,

..

k. ,
,
opIndex.

,
a[b,, b2,

bJ =


a.opIndexAssign(c, b,, b2,

bk)


,
<on> a[b,, b2,

., b J

<on> ++, --, -, +, ^, *,



a.opIndexUnary!"-on'"(b,, b2,

bk)


,
1 2.2.2.
, ,

a[b,, bj,

., b J <on>=


a.opIndexOpAssign!"'CW7'''(c, b2,

bk)

457

12.6.

,
, ,
.
? ,
- opIndex
, :
struct MyArray(T) {
ref T opIndex(uint i ) {

>

}
--
T, .
, MyArray! int ,
a[7] *= 2 opIndex
ref int,
2. ,
.
, .
, ,
, . ,
,
, .
:
. -
, bool.
ref bool,
.
,
.
:
. .
,
,
, .
:
SparseArray!double ;
a[8] += 2;

,
, : a[8] ,
2;
-2, , ,
;
-2,
.

458

12.

, , opIndex
.

12.7.
D a[] a[b, .. 2] (.
4.1.3).
. ,
.
, a[]
a . o p S li c e ( ) ,a a [ b ,.. b;,]-BBHflea.opSlice(b,, ).

, . 1^5 : <on> a[] .!
"<on>"(), <on> a[b, .. 2].!"<>"(1, b2) ,a [] = c ea.opSliceAssign(c),a[b, .. b2] = c-B a .op S liceA ssign (c, b,, b2) ,a [ ] <on>=cBa.opSliceOpAssign!"<on>''(c),HHaKOHen,a[b, .. b2] <on>=c-Ba.opSliceOpAssign!''<on>"(c, b,, 2).

12.8. $
D
$. , [0 .. $ - 1] .
, , $
D.
, $
, , ,
,
.
$ :

[<>], :
<> $, a.opDollar().
;

[<:>, ..., <>]: <^ $,


.opDollar! (!)();

[<> .. <2>]: <> <2>


$, a.opDollar().

- ,
.

12.9. foreach

459

12.9. foreach
,
. ,
, , ,
. , :
,
.

12.9.1. foreach
, foreach
( ),
: empty bool, ,
, front,
, popFront()1,
.
:
s t r u c t SimpleList(T) {
private:
s t r u c t Node {
T _payload;
Node * _next;

}
Node * _root;
public:
0property bool empty() { return !_root; }
3property ref T f r o n t( ) { return _root._payload; }
void popFront() { _root = _root._next; }

}
,
:
void process(S im p leL ist!int 1 st) {
foreach (value; 1 st) {
.. / / i n t

)
}
foreach
for, , ,
:
void process(S im pleL ist!in t 1st) {
for (auto _ = 1st; !_c.empty; __c.popF ront()) {

foreach_reverse popBack back


. - . . .

460

12.
auto value = _c . f r o n t;
/ / in t

}
>
value ref,
value
__c.front. ,
. , front
, 1-
.
, :
l s t [ ] , __
l s t [ ] , 1st. ,
,
.

12.9.2. foreach
,
, .
,

.
, ,
( ).
foreach ,
opApply1. :
import s t d . s t d i o ;
c l a s s SimpleTree(T) {
p riv ate:
T _payload;
SimpleTree _ l e f t , _ right;
public:
th is (T payload) {
_payload = payload;

}
/ /
i n t opApply(int d e l e g a te ( r e f T) dg) {
auto r e s u l t = dg(_payload);
i f ( r e s u l t ) return resu lt;

1 opApplyReverse,
foreach_reverse opApply foreach. - .
. .

12.9. foreach

461

lf (_ left) {
r e s u lt = _left.opApply(dg);
i f ( r e s u l t ) return re su lt;

}
i f ( _ rig h t) {
r e s u lt = _right.opApply(dg);
i f ( r e s u l t ) retu rn re su lt;

}
return 0;

>
}
void main() {
auto obj = new Sim pleTree!int(1);
o b j . _ l e f t = new Sim pleTree!int(5);
o b j._ rig h t = new SimpleTree!int(42);
o b j . _ r i g h t . _ l e f t = new SimpleTree!int(50);
o b j. _ r i g h t._ r ig h t = new SimpleTree!int(100);
foreach ( i; obj) {
w r i te l n ( i) ;

}
}
:
1

5
42
50
100

( { writeln(i); })
opApply.
, ,
break, 1
, result opApply.
, opApply :
,
. .

empty, front popFront, .
, opApply
.
.

foreach opApply. 1, ,
. ,
, foreach,
- . -

462

12.

opApply ,
, foreach :
/ / object.opApply(delegate i n t ( r e f k, ref V v ) { . . . } )

foreach (k, v; o b je c t) {
}
,
opApply.
V[K] , ,
opApply, V .

12.10.


, opBinary(string)(T).
,
. ,
, ,

.
- , , opBinary,
,
:
class {
/ / ,
opBinary (string op)(A rhs) {
/ / ,
return opBinary(op, rhs);

}
/ / ,
opB in ary (string op, rhs) {
switch (op) {

case "+":
/ /

break;
case "- ':
/ /

break;
>
}
>
,
, - ,
.

463

12.11. - : opDispatch


opBinary:
class {
/ / ,
opBinary(string op)(A rhs) {
/ / ,
s t a t i c i f (op == "+") {
return opAdd(rhs);
} e ls e s t a t i c i f (op == "-") {
return opS ubtract(rhs);

}
>
/ /
opAdd(A rhs) {
/ /

>
opSubtract(A rhs) {
/ /

}
}
. ,
,
, .

12.11. - : opDispatch
, ,
, - opDispatch.
D .
T opDispatch,

a.fun( <apr,>..........

<>)

a.opDispatch! "fun"( <apr^,

<>)

fun, ,
, ,
.
opDispatch
.
opDispatch,
. ,
_
(cam el-case) :

464

12.
import std .cty p e;
s t r i n g underscoresToCamelCase(string sym) {
s t r i n g r e s u lt;
bool makeUpper;
foreach (; sym) {
i f ( == _) <
makeUpper = tru e;
} else {
i f (makeUpper) {
r e s u l t ^= toupper(c);
makeUpper = fa ls e ;
} else {
r e s u lt ~= ;

}
}
}
return r e s u lt;

>
u n ittest {
assert(underscoresToCamelCase("3flpaBCTByi*_MHp'') == "");
assert(underscoresToCamelCase("_a") == 'A");
assert(underscoresToCamelCase("abc") == "abc");
assert(underscoresToCamelCase("a_bc_d_') == "aBcD");

>
underscoresToCamelCase,
opDispatch,
.__()
.() -
.
class {
auto opD ispatch(string m, Args. )(Args args) {
retu rn m ix in (''th is. "^underscoresToCamelCase(m)^''(args)");

}
i n t doSomethingCool(int x, i n t ) {
retu rn 0;

>
>
u n ittest {
auto = new ;
a.doSomethingCool(5, 6);
/ /
a.do_something_cool(5, 6); / / ,
/ / opDispatch

}
,
opDispatch a.opDispatch! "do_some-

12.11. - : opDispatch

465

thing_cool''(5, 6). opDispatch, , "this.doSomethingCool(args)", mixin.


, args 5, 6,
mixin a.doSomethingCool(5, 6) -
. !

12.11.1. opDispatch
, , opDispatch
,
. , JavaScript Sm all
talk,
. D: Dynamic,
, .
-,
. Variant
std.variant. : Variant
. Variant

. ,
, (
this) Dynamic, Variant, Variant.
import s td .v a r ia n t;
a l i a s Variant delegate(Dynamic s e l f , V aria n t[] a r g s . . . ) DynMethod;

... DynMethod
, .
Dynamic, , ,
.
, Dynamic ,
DynMethod:
c la s s Dynamic {
priv ate DynMethod[string] methods;
void addMethod(string name, DynMethod m) {
methods[name] = m;

>
void removeMethod(string name) {
methods.remove(name);

}
/ /
Variant c a l l ( s t r i n g methodName, V aria n t[] a r g s . . . ) {
return methods[methodName](this, args);

>
/ / opDispatch
Variant opD ispatch(string m, A rg s ...)(A rg s args) {
V ariant[] packedArgs = new V a r ia n t[a rg s .le n g th ];

466

12.

foreach ( i , arg; args) {


packedArgs[i] = V ariant(arg);

}
return call(m, args);
}
}
Dynamic :
unittest {
auto obj = new Dynamic;
o b j . addMethod("sayHello"
delegateV ariant(Dynamic, V a r i a n t [ ] . . . ) {
writeln("3flpaecTByCi, !");
return V ariant();

});
o b j.say H e llo (); / / ', !"

>

,
. :

, .
. ,
, . Dynamic
. ,
getMethodInfo(string),
.
, ,
.
,
(Variant )
, (, -
).
:
,
, ,
.

12.12.
.
, ,,
&&, ||, is,
?:, &
typeid. ,
, .

467

12.12.

, . , -
,
. D :
,
- (D om ain-Specific Embedded Lan
guage, DSEL). - ,
mixin (. 2 .3 .4 .2 )
(. 5.12).
DSEL,
,
D. ,
.
opDispatch ,
.

(, ,
a.helloWorld() a.heloWorld(),
,
).
. 12.1 .
,
.
12.1.

...

'on>a, <on< {+, -, ^, *, ++, --} a.opUnary!"<on*''0


++

((ref x) {auto t=x; ++x; return t;})(a)

a--

((ref x) {auto t=x; --x; return t;})(a)

cast(T)

a.opCast!(T)()

? 't > : -

cast(bool) ? <,< : <2>

if () <>

i f (cast(bool) ) <>

<on> b, -on> e {+, -, *, /,


%, &, |, ", , , > , -, in}

a.opBinary! ''-on>"(b) b.opBinaryRight! "<on"(a)

== b

b - : object.opEqua l s ( a , b) ( . 6 .8 .3 ) . b
: a.opEquals(b).
a.opEquals(b) b.opEquals(a),

!= b

!( == b),

468

12.

12.1 ()

...

< b

a.opCnp(b) < .() > 0

<= b

a.opCmp(b) <= .() >= 0

> b

a.opCmp(b) > .() < 0

>= b

a.opCmp(b) >= .() <= 0

= b

a.opAssign(b)

<on>= b, <on> e {+, -, *, /,


%, &, |, ^, , , > . '} ________

a.opOpAssign!"<on<"(b)

a[b,. bj. .... b J

a.opIndex(b,, ...... bk)

a[b,. ...... bJ =

a.opIndexAssign(c, b,, b2, ..., bk)

<on-a[b,, b2...... b J ,
<on> e {++, --}

a.opIndexUnary(b,, ...... bk)

a[b,, b2...... bk] <on>= ,


<on> e {+, -, *, /,%, &, |, ^,
, , >, -}

a.opIndexOpAssign!"<on>''(c, b,, b2...... bk)

a[b, .. ]

a.opSlice(b, .. b2)

<on> a[b, .. ]

a.opSliceUnary!"<on'"(b,, )

a[] =

a.opSliceAssign(c)

a[b, .. ] =

a.opSliceAssign(c, b,, )

a[] <on>=

a.opSliceOpAssign!"<on'"(c)

a[b, .. b2] <on>=

a.opSliceOpAssign!''<on>"(c, b,, 2)

13



, , ,
.
,
.

,
, D
,
, ,
. D
- ,
;

. ,
,
.
D,
, ,
. (
.)
, D:


,
. ,
(m essage passing),
, .

470

13.


. ,
,
, .
D ,
.

D
, .


.
D ,
.
,
-
( ).

, .

D,
@safe,
.
.

, asm
.
,
.

, ,
,
.

13.1.

,
, -. , ,
,
.
,
1; , , ,
,

1 24
. - . .

13.1.

471

.

.
, ,
.
, ,
,
. -,
[16]:
, ,
. ,
,
, . .
. ,

,
. ,
. -

( ) .
- ,
,
( ,
: USB ,
SATA PATA,
, -
. , ,
?).
,
. ,
,
,
- ,
[22]. ,
, .
;

,
.
- ,
,
, ;

,

. :

472

13.

.
, , .

, :
,
, [37].
,
(immutable, ) -
3 0 0 0 0 0 0 0 0 . (

) ,

.
.
10 ,
4 ,5 ( ,
) .
,
,
, -
,
.
, , .
,
;

, .
,
, .

,
: ,
. -
,
.
,
.

, .
,
.
-
,
, , . ,
, - .

13.2.

473

. .
.

13.2.

- ,
,

.
, , ,
2 0 00-
.
, 1
, 1960-x.
,
,
,
.
. (
, )
.
,
,
,
.

, .

',
,
,
-,
( ) (
). , , -
, ,
. ,

, ,
,
. (threads).

1

.

474

13.

, ,
; :
.
,
,
. ,
, ,
: , .
,
, ,
.
, ,
(
). X X ,
(
,
),
, .
,
.
( , ++, Java)

,
. , ,
(
, )
.
, ,
, .
, A PI (,
MPI [29]) ,

, ().

, :
, -
. - .
- ,
,
. ( , , ,
, : !..)
, ,
,
, .

13.2.

475

Erlang. 1980-
-
. , ,
,
,
- .
,
Erlang .
,
,
(
!).
2010-e.
, -
. ,
.

- , ,
. , ,
,
.
, ,
: (
),
.
-,
.

, + .

.
, ,
, , .
,
1:
- ,

, .

( ):
,
.

1 ,
, - .

476

13.

, ,
,
: x, ,
,
x. -
.


.


Java.
2001 [8, . 51, . 204]:

,
, ...
,
-
.
:

,
, . ,
2 0 0 8 1 [9] ,

. , ,
, : 1)
,
-
, 2) ,
, .
,
Erlang [5, 20, . 363]:

. :
.
. , 2.
", .
,
.
? ,
.


, , - ,
.
E r la n g .

13.3. , , ( )

477

2001 ; ,
, ,
;
.
,
,
.
, E rlang
,
.

13.3. , ,
( )

D : ,
D ,
- .
( )
;
D.
,
, ,
. . -, D
-

. -, -
, .
,
shared.
, :
int perThread;
shared int perProcess;
(
) ,
, D perThread
.
in t, ,
( ) .
perThread
, (thread-local
storage, TLS). ,
TLS,
. ,

478

13.

,
. ,
, ,
TLS, .
. -, ,
,
; perThread
, . -
, shared , ,
, perProcess
. ,
,
. D :

, , ,
, ,
,
. ,
, shared,
. (
shared ,
.)
,
,
,
.
,
- .
,
,
D.
,
, - ,
. Erlang ,
(M essage Passing
Interface, MPI) [29], .
1. ,
,
. ,
,
= + [54] :
-
. " , :

1 .

479

13.4.

,
. ,
,
( F IF O )
,
;
- .
-,
, ,
1. D :

- , .

13.4.
spawn, :

im port std.concurrency, std. stdio;


void main() {
a u to low = 0, high = 100;
spawn(&fun, low, high);
fo rea c h (i; low
high) {
writeln("0cHOBHoCi :

i);

>
>

void f u n ( in t low, i n t high) {


fo rea c h (i; low
high) {
writeln("fl04epHkm : ", i);

}
>
spawn fun <a,>,
<2>,..., <'. n
fun, , fun(<a,>, <2>......... <>)
.
. spawn , 30Bfun(<a,>, <2>........ <'), .
, spawn , , -

( ).

20 0 .

1 : ,
,
( ). . ..

480

13.

; , 100
, 100 ,
, .
.
writeln ,
. , ,
, .
main fun
, ,
, .

,
; , main
, .
,
, . , :
stdout .
:
std .std io, , stdout
. .

13.4.1.
spawn?
: ,
( fun),
.
, ( ref),
(, ), .
, :
import std.concurrency, std .std io ;
void mai n() {
auto low = 0, high = 100;
auto message = ", #";
spawn(&fun, message, low, high);
foreach (i; low
high) {
writeln("0CHOBhOfi : '', message, i ) ;

>
}
void fun(string text, int low, int high) {
foreach (i; low
high) {
writeln(''flo4epHHii : "

>
}

te x t, i) ;

13.5.

481

, ,
.
. , message
. ,
, ,
shared.
. ?
8 , immutable
: ,
.
(. 8.2), string -
immutable(char)[]. , ,
- -
, ,
.
, ,
immutable. ,
string, .
, immutable
,
.

13.5.
, ,
. ,
. , :

:
:
:
:

0
0
1
1

: 99
: 99


:
, -
. -
, ,
.
,
.
, ,
.
, .

482

13.

,
spawn (th read id),
tid. ( tid - Tid.)
, , tid ,
. ,
Tid, . :
import std.concurrency, s t d . s t d i o , std.exception;

void main() {
auto low = 0, high = 100;
auto t i d = spawn(&writer);
foreach ( i; low
high) {
writeln("0cHOBHOii :

i);

t i d .s e n d ( th i s T id , i ) ;
enforce(receiveO nly!Tid() == t i d ) ;

}
}
void w r i t e r ( ) {
for (;;) {
auto msg = receiveOnly!(Tid, i n t ) ( ) ;
writelnCflonepHHki : '', msg[1]);
m sg[0].send(thisT id);

}
}
writer :
. Tid,
spawn,
send.
: Tid (
thisTid) ,
. ,
, ,
receiveOnly. send receiveOnly
: send
receiveOnly . receiveOnly 1
(), receiveOnly ,
, receiveOnly!bool()
; , receiveOnly MessageMismatch.
main foreach
writer, -, writer
, ,
Tid int.
receiveOnly!(Tid, int)(); ,
-
, receiveOnly

13.6. receive

483

. , receiveOnly
writer tid.send(thisTid, i) main.
msg Tuple! (Tid, int).
,
.
, , Tuple
. , receiveOnly!int() int, aHeTuple!int.
writer. , ,
( ). , msg
msg[0] ( Tid),
msg[1] - ( ). ,
writer , ,
Tid
- ,
. , , -
, - . .
, ,
, .
Tid -
, int bool.
, ,
.

13.6.
receive
,
. , receiveOnly,
. , receiveOnly
, int string.
receive,
.
receive :
receive(
(strin g s) { writeln(''n<wy4eHa
s); },
(int x) { w rite ln ('T ^ y 4eH0 " x); }

);
send
:
send(tid,
send(tid,
send(tid,
send(tid,

"");
5);
'a');
42u);

484

13.

send string
, receive ;
int .
, -
- - ( )
:
void h a n d le S trin g (s trin g s) {

}
receive(
&handleString,
(int x) { writeln("fl0nyHeH0 "

x); }

);
;
, ,
char uint
in t. , ,
-.
se n d (tid ,
se n d (tid ,
se n d (tid ,

''hello"w); / /
5L);
//
42.0);
//

UTF-16 (. 4.5)
long
double

receive ,
( receiveOnly).
,
(m ailbox) , receive
, .
receive ,
, ,
.
-
, receive ,
.
Tuple, send/receive
. :
receive(

(long x, double ) {
(int x) {
}

),

);
,
receive(
(Tuple! (long, double) tp ) <
(int x) { . . }

},

);
, send(tid, 5, 6.3),
, .

485

13.6. receive

receive - receiveTimeout,

. receiveTimeout :
.
receiveTimeout , false:
auto gotMessage = receiveTimeout(
1000, / /
( s t r i n g s ) { w r i t e l n C T ^ y s e H a " s ) ;
(int x) { writelnC'flonyneHo '' x ); }

);
if

(!gotMessage)

s t d e r r . w r i t e l n ( " B u n o n H e H n e .");

13.6.1.
:
receive(

(long x) {

},

( s t r i n g x ) { ..

(int

x)

},

);
: receive ,
.
int
.
receive ,
. ,
catch try, -
.

- ; , , ,
receive.

receive ,
. <,> <2> , ,
receive <}> <C6a/,>,
receive , <}>
<^>. , , <<
<2>,
.
, <>
long, <2> - int.

486

13.

13.6.2.

- , ,
?
-
Variant receive. :
receive(

(lo n g x ) { . . . },
(strin g x ) {

(d o u b le x, d oub le
(V a ria n t any) {

},
)

},

);
Variant, std.variant, -
, , receive
Variant
, receive Variant
, .
Variant
-
.

13.7. -


.
getchar/putchar! [34, 1, . 15]. ,
, , ,
,
,
,
.
:
1. .
2. , .
3. .
4. , 1.

( ) .
, ( , )
,
.

13.7. -

487


: , -, ,
, .


. (
,
/ ),
.
-, -, ,
/:
1. , ,
, .
2.
.
3. , .
4. ,
.
5. , 2.
,
.
.

,
. ,
/
:
import std.concurrency, s t d . s t d i o ;
void main() <
enum bufferSize = 1024 * 100;
auto t i d = spawn(&fileWriter);
/ /
foreach (ubyte[] buffer; stdin.byC hunk(bufferSize)) {
send(tid, b u ffe r.id u p );

}
}
void file W r ite r( ) {
/ /
for ( ; ; ) {
auto buffer = receiveOnly!(immutable(ubyte)[])();
stdout.raw W rite(buffer);

}
}

488

13.


:
immutable(ubyte)[],
ubyte.
foreach ,
immutable(ubyte)[] bufferSize.
byChunk (
buffer), idup.
foreach;

. ,

immutable; idup dup, send .

13.8.
- ,
writer, 13.5,
fileW riter 13.7:
. ,
, , main fileW riter
,
; , main
fileW riter: , .
.
, , ;
-
. API

,

- .
D .
-;
, spawn. , setOwner(tid). ,
.
/
, -
receive
OwnerTerminated. ,
receive
; receive ,
OwnerTerminated. , -

13.8.

489

receive ( receiveOnly, )
,
,
, .
. ,
, ;
, , .

.

.
,
. main
receive , ,
. ,
(
), receive .
OwnerTerminated;
, ,
.
, , .
,
main main (
receive ) .
- , ,
? . ,
, :
,
OwnerTerminated (
,
). ,
main , ,
fileW riter.
,
, 2 0 0
, : main
( ) .
,
OwnerTerminated.
, ,
, -
, , OwnerTerminated :
/ /

void f ile W r ite r ( ) {

490

13.
/ /
f o r (b o o l running =
r e cei v e(

tr u e ;

running;

) {

(im m u ta b le (u b y te )[]

buffer) { t g t . w r i t e ( b u f f e r ) ;
(OwnerTerminated) { running = f a ls e ; }

},

);
>
stderr.wri tel n("Bunofl HeHne .");

}
main fileWriter
, . ,
, ?
tg t, write
. send
( 0wnerFailed), , . ,
(
), send,
, ,
- OwnedTerminated.

, , .
,
,
, .

,
,
.
:
,

. ,
, ,
. , ,
.
,
.

13.9.
, ,
,
.
- . read,
main , ,

13.9.

491

, . ,
, -
, receive
. ,
?
,
,
. , ,
.
, receive ,
,
. . - -,
prioritySend send.
, -,
. T
prioritySend receive -
:

receive T,

-
() .
,

receive (
).

receive T (
receive
) T
Exception, receive .

receive T T
Exception, receive PriorityMessageException!T.
message.

, OwnerFailed
, ,
prioritySend.
main fileW riter
( receive); ,
,
.
, ,
, ,
.

492

13.

13.10.
/
,
. ,
,
,
(
) (, ).
( ,
main) ,
, ,
. ,
,
.
, A PI

, ,
. :
/ / std.concurrency
void setMaxMailboxSize(Tid t i d , s iz e _ t messages,
bool function(T id) onCrowdingDoThis);

setMailboxSize,
:
, , mes
sages, onCrowdingDoThis(tid). onCrowdingDoThis(tid)
fa ls e , .
,
, , messages,
tid .
.
setMaxMailboxSize ,
, , . , ,
,

. :
-? ,
,
: ,
,
.
, ,
: ,
,
. :

13.11. shared

493

/ / std.concurrency
enu m OnCrowding { block, throwException, ignore }
v o i d setMaxMailboxSize(Tid t i d , s iz e _ t messages, OnCrowding doThis);

-,
. ,

setMaxMailboxSize(tid, 1024, OnCrowding.block);

spawn.
, ,
. -
;
, ,
.
- ,
, .

13.11. shared
shared 13.3.
shared ,
.
,
,
.

s h a r e d u i n t threadsCount;

D shared(uint),
.
.
shared : , threadsCount
,
. :
v o i d bumpThreadsCount() {
++threadsCount; / / !
/ / shared i n t !

)
? - , , ++threadCount
; ,
: -
. threadCount ,
, , threadCount
.

494

13.

.
-
std.
concurrency:
import std.concurrency;
shared uint threadsCount;
void bumpThreadsCount() {
/ / std.concurrency
/ / atomicOp(string o p ) (r e f shared u int, i n t )
atomicOp!"+="(threadsCount, 1); / /

>

, shared
send receive.

13.11.1. :
shared
8 , const immutable
(,
): ,
,
. ,
immutable, .
,
(immutable), . ,
,
, .
immutable,
. , immutable
,
,
.
,
.
shared.
, shared
. .
shared int* pInt;
(. 8.2)

shared(int*) pInt;
pInt : ,
, , .

13.12.

495

, pInt
, ,
- .
: ; , ,
, 1. ,
, ,
,
, .
- , .
,
,
.

.
, .
:

s h a r e d (in t) * pInt;
,
, () .
.
. :

i n t sh a re d (* ) pInt;
,
(*) - ( ,
).
shared
, - :

shared.

.

13.12.

,
.

.

, const,
, , .
shared(const(Money)*).

496

13.

(shared) ,
:
( real), , , ,
.

.
real , ,
.
real . Intel real 80 , -
32- . , real
,
, -
.
,
shared
.
shared(T*) shared(T)*
.
std.concurrency.

13.12.1.


, D :


,
;



,
.

, .

,
.

. :
,
.

( ),
,
,

13.13.

497

.
.
,

-
.
- .
,
,
.
, ,
.
, ,
, ,
.


,
.

13.13.

.
-
,
,
,
. 1.
, ,
,
. ,
, () ,
, () .
,

:
, ,

1 - , W in d o w s
,
, -
,
.

498

13.

. ( , ,

.)
, , !
- : ,
,
. ,
, :
import std.contracts;
/ /
class BankAccount {
private double _balance;
void deposit(double amount) {
_balance += amount;
}
void withdraw(double amount) {
enforce(_balance >= amount);
_balance -= amount;
}
property double balance() {
return _balance;
}
}
+= -= :
, -
- - .
, _ 1 += amount _balance =
_balance + amount, , _balance _amount
( ),
, _balance.
- .
, _ba
lance == 100.0. ,
, deposit(50). 100.0
, withdraw(2.5). (
.) ,
, , _balance,
97.5.
, 100
, .
deposit(50) 150
_balance.

13.13.

499

. , ( :
,
- ).
- Mutex,
,
, balance:
/ / D
/ /
class BankAccount {
private double _balance;
private Mutex _guard;
void deposit(double amount) {
_guard.lock();
_balance += amount;
_guard.unlock();

}
void withdraw(double amount) {
_gu ard.lo ck();
try {
enforce(_balance >= amount);
_balance -= amount;

} finally {
_guard.unlock();

}
}
eproperty double balance() {
_guard. lo c k ( );
double r e s u lt = _balance;
_guard.unlock();
return resu lt;

}
}
_balance ,
_guard. ,
_balance _guard ,
double ,
,
. , -


,
;
- (, D
).
, ,
-
,
_balance, .

500

13.

, , ,

,
, ,
, . (?
,
, ,
, ?) ,

,
. ,
,
_balance.
Mutex

, ,
(
),
Lock,
. ,
[50].
BankAccount :
/ / ++: ,
c l a s s BankAccount {
p r iv a te :
double _balance;
Mutex _guard;
public:
void deposit(double amount) {
Lock lock = Lock(_guard);
balance += amount;

}
void withdraw(double amount) {
Lock lock = Lock(_guard);
enforce(_balance >= amount):
balance -= amount;

}
double balance() {
Lock lock = Lock(_guard);
return _balance;

}
}
Lock
:
,
. Java, C #
, _guard

13.13.

501

,
. , Java, :
/ / Java: ,
/ / , synchronized
c la ss BankAccount {
priv ate double _balance;
public synchronized void deposit(double amount) {
_balance += amount;

}
public synchronized void withdraw(double amount) {
enforce(_balance >= amount);
_balance -= amount;

>
public synchronized double balance() {
return _balance;

>
>
C # , ,
synchronized [MethodImpl(MethodImplOptions.Synchronized)].
, : ,
, , ,
. ,
,

, ( ,
,
, , ).


; (
,
)
[53].
.
D
.
: ,
. BankAccount, D :
/ / D: ,
/ /
synchronized c la s s BankAccount {
priv ate double _balance;
void deposit(double amount) {
_balance += amount;

>
void withdraw(double amount) {

502

13.

enforce(_balance >= amount);


_balance -= amount;
>
9property double balance() {
return _balance;
}
}
D synchronized ,
1.
BankAccount, D,
:
,
-
_balance. D

, ,
, .
,
, ;
, .
synchronized
shared(BankAccount)
.
,
. ,
11.1
(public)
.
syn
chronized :

(public) ;

(protected)
;

(pr ivate)
.

13.14.

(shared)

shared . , synchronized
1 , D '
( ). - . . .

13.14.

503

,
.
synchronized ,

,
synchronized.
.
,
, .
, synchronized ,
, ,
( , ).
.

13.14.1. ==
, ,
synchronized
:
. ,

, .


. ,
, :
double * nyukNyuk1; / / : shared
void sneaky(ref double r) { nyukNyuk = &r; }
synchronized c l a s s BankAccount {
priv ate double _balance;
void fun() (
nyukNyuk = &_balance; / / ! ( )
sneaky(_balance);
/ / ! ( )

}
}
fun _balance
.
, -

.
. ,
1 nyukNyuk (-) - . - .
.

504

13.


- , .
; ref
.
, .

13.14.2.

==

, synchronized,
- . ,
-
. ,
, ,
. , (,
,
BankAccount) , , ( ),
,
,
(shared). (syn
chronized) :

( ),
(
shared);

-, T[], shared(T)[]; ( ) , (
) ;

-, T*, sha
red(!)*; ( ) , (
, ) ;

-, T, shared(T).
(
), .

,
.
: , ,
,
-
synchronized.
. ,
BankAccount
double:
/ /
c l a s s List(T) {
void append(T value) {

13.14.

505

}
>
/ /
synchronized c la s s BankAccount {
p rivate double _balance;
p rivate List!double _tran sa ctio n s;
void deposit(double amount) {
_balance += amount;
_transactions.append(amount);

}
void withdraw(double amount) {
enforce(_balance >= amount);
_balance -= amount;
_t r an sa ctio n s. append(-amount);

}
eproperty double balance() {
return _balance;

List
, ,
!
BankAccount
,
. , List

, .
, . D , ,
, append
shared(List!double) .
,
. List ,
,

.
List, List, ,
, ,
,
- .
,


.
,
.

506

13.

,
( D) ,
.
- ,
, BankAccount
_transactions, , BankAccount
_transacti
ons>.
, _transactions
BankAccount, ,
, .
, [25, 2, 11, 6],
, .

.
,
, D
. ,
( D
[42]), ,
, ,
, , .

13.14.3.
D ,
: /
.
:
/ / o b je c t.d
setSameMutex(shared Object ownee, shared Object owner);

obj obj.setSameMutex(owner)1, obj


, owner.
, owner
obj. ,
BankAccount List.
/ /
synchronized c l a s s List(T) {


( . 5 .9 ) , obj.setSameMutex(owner) setSameMutex(obj, owner). ,
. - . . .

13.14.

507

void append(T value) {


}
}
/ /
synchronized class BankAccount {
private double _balance;
private List!double _ transa ctions;

this() (
/ /
setSameMutex(_transactions, t h i s ) ;

}
}

List (-). _transactions
,

. _transactions
- :
BankAccount.
: ,
. :
BankAccount, List.
_transactions
th is. ,
,
,

.

13.14.4. : shared
.
, _transactions
BankAccount,
shared _transactions :
/ /
class List(T) {

void append(T value) {


>
}
synchronized class BankAccount {

508

13.
p r iv a te double _balance;
p r iv a te List!double _ tran sa ctio n s;
void deposit(double amount) {
_balance += amount;
(c a st( L is t! d o u b le ) _ t r a n s a c t i o n s ) . append(amount);

}
void withdraw(double amount) {
enforce(_balance >= amount);
_balance -= amount;
( c a s t( L is t! d o u b le ) _ tr a n s a c t i o n s ) . append(-amount);

}
0property double balance() {
return _balance;

}
}
List
, . :
,
, ,
.
, , ,
, , ,
cast -
.

13.15.
synchronized
- , ! ,
, ,
, - ( )
.
: BankAccount
( , checking savings);
.
:
/ / . 1;
void tr a n s f e r( s h a r e d BankAccount source, shared BankAccount ta rg e t,
double amount) {
sou r c e .withd raw(amount);
t a r g e t . deposit(amount);

}
;
transfer .
inspectForAuditing, .

13.15. synchronized

509

,

, transfer.
synchronized:
/ / . 2:
void tr a n s f e r( s h a r e d BankAccount source, shared BankAccount ta r g e t,
double amount) {
synchronized (source) {
synchronized ( t a r g e t ) {
source.withdraw(amount);
t a r g e t . deposit(amount);

}
}
}
synchronized
.
.
transfer ,
():
,
,
. , che
cking savings, checking, ,
savings checking,
savings.
, ,

. .
synchronized
:
/ / . 3:
void tr a n sfe r(sh a re d BankAccount source, shared BankAccount ta r g e t, double
amount) {
synchronized (source, t a r g e t ) {
sou rc e . withd raw(amount);
target.deposit(am ount);

>
>

synchronized
.
,
,
. , .

510

13.


.
, .
synchronized , ,
, . ,
, :
, -
, . synchro
nized

.

13.16.

, ,
1960-x. 1972 [23]
,
, . ,
,
,
. ,
,
--.
, 1990 , ,
: , -
,
.
, ,
.
(1991) [3]
.
,
,
. , ,
in t,
, ,
+=, ,
*=, . ,
, .
,
,
--, --
FIFO.
,

13.16.

511

. ,

:

. ,
, ,
.
,
(compare-and-swap).
.
:
/ /
bool cas(T)(shared(T) * here, shared(T) ifT h is, shared(T) w riteT his) {
i f (*here == ifT his) {
*here = writeThis;
return true;

>
return fa lse ;

}
cas
,
, ;
. ,
. cas
. T
,
( 32 64 ).

(double-word com pare-and-swap), cas2.
cas2 64- 32-
128- 64- .
cas2, D

(cas),
. D
cas int, long, flo a t, double, ,
.

13.16.1.


cas.
: cas
, , .
cas
- . ,

512

13.

,
[57].

cas, shared
:
shared s t r u c t LockFreeStruct {

}
shared c l a s s LockFreeClass {

>
:
,
. ,
, , cas, ,
, ,
. :
- , - ,
, .

13.16.2.
. :
,
,
:
shared s t r u c t Stack(T) {
p r iv a te shared s t r u c t Node {
T _payload;
Node * _next;

}
p r iv a te Node - _root;
void push(T value) {
auto n = new Node(value);
shared(Node)* oldRoot;
do {
oldRoot = _root;
n._next = oldRoot;
} while (!cas(&_root, oldRoot, n));

}
shared(T)* pop() {
ty p e o f( r e tu r n ) r e s u lt;
shared(Node)- oldRoot;
do {
oldRoot = _root;

13.16.

513

i f (!oldRoot) return n u ll;

r e s u l t = & oldRoot._payload;
} w hile (!cas(&_root, oldRoot, oldRoot._next));
return r e su lt;

>
}
Stack , :
. Node -
+ , Stack
.
do/while ,
, ,
; ,
-. push : ,
. _root
,
eeI ,
- ,
push , ,
, , oldRoot,
.
pop , .
, pop ,
( , ,
).
,
.
, pop push:
_root ,
,
.
.
Stack ,
;

Stack.
, .
? .
-
. , in t,
5, 10,
5. -
cas, _root 10.
,

514

13.

5 ,
, _ r o o t .
;
. ,
,

[30]. ,

_ n e x t. ,
( ),
.
shared s t r u c t SharedList(T) {
shared s t r u c t Node {
p r iv a te T _payload;
p r iv a te Node * _next;
6property shared(Node)* next() {
return c le a rls b (_ n e x t) ;

>
bool removeAfter() {
shared(Node)* thisNext, afterNext;
/ / 1: _next ,
/ /
do {
thisNext = next;
i f (!th isN ex t) return f a lse ;
afterN ext = thisN ext.next;
} while (!cas(& thisN ext._next, afterN ext, se tls b ( a f te rN e x t)) );
/ / 2: ,
i f (!cas(&_next, thisNext, afte rN e x t)) {
afterN ext = th isN ext._next;
while ( ! h a s ls b ( a f te rN e x t)) {
thisN ext._nex t = thisNext. next.next;

}
_next = afterNext;

>
}
void in se rtA f te r( T value) {
auto newNode = new Node(value);
for ( ; ; ) {
/ /
auto n = _next;
while (n && h a s lsb (n )) {
n = n._next;

}
/ / ,
auto afterN = n._next;

13.17.

515

newNode._next = afterN;
i f (cas(&n._next, afterN, newNode)) {

break;
>
}
}
}
p r iv a te Node * _root;
void pushFront(T value) {
.. / / To , Stack.push

>
shared(T)* popFront() {
/ / To , Stack.pop

>
>
, , , ,
. -,
( Node _next,
) -
. -, .
, , ,
.
clearlsb, setlsb haslsb ,
; :
. setlsb(T)(T* p) {
return cast(T*) ( c a s t( s iz e _ t) p | 1);

13.17. 1
s ta tic th is(),

:
module c o u n t e r s ;in t counter = 0;
sta tic th is()

{
counter++;

}
,
counter. ,
.

1 ,
,
. - . . .

516

13.

im p o rt std.concurrency, std.stdio;
i n t counter = 0;
s ta tic th is ()
<
counter++;
writeln(''CiaTH4ecKHfi : counter = " counter);

v o id main() {
w riteln("0cH O B H O ti

");

spawn(&fun);

vo id fun() {
writeln("fl04epHkM ");

}
, :
: c o u n t e r = 1

: c o u n t e r = 1

,

, shared s ta tic th is(),
- shared sta tic
^thisQ:

im p o rt std.concurrency, std .std io ;


sh a re d i n t counter = 0;
sh a re d s t a t i c t h i s ( )
{
counter++;
^1(" : counter = " counter);

v o id main() {
writeln("0cHOBHOfl

");

spawn(&fun);

>

vo id fun() {
writeln("flo4epHk^ '');

517

13.18.

:
:

c o u n te r = 1


, .

,
.

13.18.
setlsb , ,
,

.
D .

-
.
. ,
, ,
, -
.

, .
: ,
D ,
.
,
(shared) . D ,
,
, .
, , - , ,
,
D,
.

[1] Alagid, S., Royer, M. Genericity in Java: Persistent and database


system s implications. The VLDB Jou rn al, 17, 4 (2008),
847-878.
[2] Aldrich, J., Kostadinov, V., Chambers, C. A lias annotations for prog
ram understanding. OOPSLA: Object-Oriented Prog
ramming, System s, Languages, andApplications, -, 2002,
ACM Press, c. 311-330.
[3] Alexandrescu, A. On iteration. In form IT ( 2009). h ttp://
erdan i.com /pu blication s/on -iteration .h tm l.

[4] Amsterdam, J. Javas new considered harmful. Dr. Dobb's Journal


( 2002). h ttp://w w w .ddj.com /java/184405016.
[5] Armstrong, J. Programming Erlang: Software for a Concurrent
World. The Pragm atic Programmers, 2007.
[6] Bacon, D. F., Strom, R. E., Tarafdar, A. Guava: a dialect of Java
without data races. OOPSLA: Object-Oriented Prog
ramming, System s, Languages, and Applications, -, 2000,
ACM Press, c. 382-400.
[7] Benoit, F., Reimer, J., Carlborg, J. The D W idget Toolkit (DWT).
h ttp ://w w w .dsou rce.org/projects/dw t.

[8] Bloch, J. Effective Java Programming Language Guide. Sun Mic


rosystem s, Inc., 2001.1
[9] Bloch, J. Effective Java. Second edition. Prentice Hall PTR, 2008.
[10] Bohm, C., Jacopini, G. Flow diagrams, turing machines and
languages with only two formation rules. C om m unications of the
A CM , 9, 5 (1966), 366-371.
[11] Boyapati, C., Lee, R., Rinard, M. Ownership types for safe program
ming: Preventingdataracesanddeadlocks. OOPSLA:
Object-Oriented Programming, Systems, Languages, and Applicati
ons, -, 2002, ACM Press, c. 211-230.
[12] Bright, W. The D assembler, h ttp://digitalm ars.eom /d/l.0/iasm .h tm l.

1 Java. . - , 2002.

519

[13] Brooks, Jr., F. P. *The Mythical Man-Month: Essays on Software


Engineering, 20th Anniversary Edition. Addison-Wesley, 1995.1
[14] Cabana, B., Alagic, S., Faulkner, J. Parametric polymorphism for
Java: Is there any hope in sight? S IG P L A N N o tices , 39,
12 (2004), 22-31.
[15] Cardelli, L. systems. 103 The Computer
Science and Engineering Handbook, A. B. Tucker, Ed. CRC Press,
1997, c. 2208-2236.
[16] Chang, R. Near speed-of-light on-chip electrical interconnects.
PhD,
, 2003.
[17] Cohen, . Java Q&A: How do I correctly implement the equals() me
thod? Dr. Dobbs Jou rn al ( 2002). h ttp ://w w w .d d j.co m /ja va /
184405053.

[18] Digital Mars, dmd - FreeBSD D Compiler, 2009. h ttp ://d ig ita lm a rs.
com /d/2.0/dm d-freebsd.h tm l.

[19] Digital Mars, dmd - Linux D Compiler, 2009. h ttp ://d ig ita lm a rs.
com /d/2.0/dm d-lin u x.h tm l

[20] Digital Mars, dmd - OSX D Compiler, 2009. h ttp ://d ig ita lm a rs.
com /d/2.0/dm d-osx.h tm l

[21] Digital Mars, dmd - Windows D Compiler, 2009 h ttp ://d ig ita lm a rs.
com /d/2.0/dm d-w indow s.h tm l.

[22] Drepper, U. What every programmer should know about memory.


E klektix, Inc. ( 2007).
[23] Easton, W. B. Process synchronization without long-term interlock.
ACM SIGOPS O peratin gsystem s review, . 6, . 1/2 (1972), . 95-100.
[24] Findler, R. B., Felleisen, M. Contracts for higher-order functions.
A C M SIG PLA N N otices, . 37, . 9 (2002), 48-59.
[25] Flanagan, C., Abadi, M. Object types against races. CONCUR 99:
Proceedings of the 10th International Conference on Concurrency
Theory, , 1999, Springer-Verlag, c. 288-303.
[26] Friedl, J. Mastering Regular Expressions. OReilly Media, Inc.,
2006.2

1 -,
. - : -, 2000.
2 . , 3- . : , 2008.

520

[27] Gamma, E., Helm, R., Johnson, R., and Vlissides, J. Design
Patterns: Elements of Reusable Object-Oriented Software. AddisonWesley, 1995.1
[28] Gove, D. Solaris application programming. PrenticeHall PTR,
2008.
[29] Gropp, W., Lusk, E., Skjellum, A. Using MPI: Portable parallel pro
gramm ing with the M essage-Passing Interface. MIT Press,
, 1999.
[30] Harris, T. L. pragmatic implementation of non-blocking linkedlists. L ecture N otes in C om puter Science 2180 (2001), c. 300-314.
[31] Herlihy, M. Wait-free synchronization. TOPLAS: A CM T ran sacti
ons on P rogram m in g L an gu ages a n d S ystem s, . 13, . 1 (1991),
. 124-149.
[32] Hoffman, D. M., W eiss, D. M., Eds. Software fundamentals:
collected papers by David L. Parnas. Addison-Wesley, 2001.
[33] ISO. The ANSI C standard (C99). Tech. Rep. WG14 N1124, ISO/IEC,
1999.
[34] Kernighan, B. W., and Ritchie, D. M. The C Programming
Language. Prentice H all, 1978.2
[35] Knuth, D. E. The A rt of Computer Programming. Vol. 2: Seminumerical Algorithms Addison-Wesley, 1997.3
[36] Korpela, J. K. Unicode explained. OReilly Media, Inc., 2006.
[37] Lee, E. A. The problem with threads. Computer, . 39, . 5 (2006),
. 33 -4 2 .
[38] Liskov, B. Keynote address - data abstraction and hierarchy.
OOPSLA: Object-Oriented Programming, Systems,
Languages, and Applications, -, 1987, c. 17-34.
[39] M artin, R. C. Agile Software Development, Principles, Patterns,
and Practices. Prentice Hall, 2002.4

1 ., P., P., .
. *.
- , 2007.
2 ., . , 2- .
, 2008.
3 . , . 2:
. - , 2007.
4 . . , ,
. - , 2003.

521

[40] Meyer, . Object-Oriented Software Construction. Prentice Hall,


1988.1
[41] Meyers, S. How non-member functions improve encapsulation. C++
users jo u rn a l, . 18, . 2 (2000), . 44 -5 2 .
[42] Milewski, B. Race-free multithreading: Ownership. h ttp ://
b a rto szm ile w sk i.w o rd p re ss.c o m /2 0 0 9 /0 6 /0 2 /ra c e -fre e -m u ltith re a d ing-ownership/.

[43] Odersky, M., Wadler, P. Pizza into Java: Translating theory into
practice. 24 SIGPLAN-SIGACT, Prin
ciples of programming languages, , 1997, ACM, c. 146-159.
[44] Parnas, D. L. On the criteria to be used in decomposing system s into
modules. C om m unications of theA C M , . 15, . 12 (1972), . 10531058.
[45] Parnas, D. L. technique for software module specification with
examples. C om m unications of th eA C M , . 15, . 5 (1972), . 3 3 0 336.
[46] Pierce, B. C. Types and programming languages. MIT Press,.
, 2002.
[47] Pike, R. UTF-8 history. 2003. h ttp://w w w .cl.cam .ac.u k/-m gk25/
u cs/utf-8-h istory.txt.

[48] Press, W.H., Teukolsky, S. A ., Vetterling, W. T., Flannery, B. P. Nu


merical Recipes: The art of scientific computing. Cambridge
University Press, -, 2007.
[49] Radenski, A ., Furlong, J., Zanev, V. The Java 5 generics compromise
orthogonality to keep compatibility. J. Sust. S o ftw ., . 81, . 11
(2008), . 2069-2078.
[50] Schmidt, D. C. Strategized locking, thread-safe interface, and
scoped locking. C++ R eport, . 11, . 9 (1999).
[51] Stepanov, A., Lee, M. The Standard Template Library. Tech. rep.,
WG21 X 3J16/94-0095, 1994.
[52] Sutter, H. Virtuality. C /C ++ Users Jou rn al ( 2001).
[53] Sutter, H. The free lunch is over: A fundamental turn toward
concurrency in software. Dr. Dobbs Jou rn al, . 30, . 3 (2005),
. 202-210.
[54] Sutter, H. Use threads correctly = isolation + asynchronous messages.
Sutters Mill ( 2009). http://herbsutter.com /2009/03/16/.

1 . -
. - , 2005.

522

[55] Sutter, H. and Alexandrescu, . ++ Coding Standards: 101 Rules,


Guidelines, and Best Practices. Addison-Wesley, 2004.1
[56] The Unicode Consortium. The Unicode Standard, Version 5.0.
Addison-Wesley, 2006.
[57] Valois, J. D. Lock-free linked lists using compare-and-swap. 14
ACM *Principles of distributed comput
ing (1995), ACM,. -, c. 214-222.
[58] Von Ronne, J., Gampe, A ., Niedzielski, D., Psarris, K. Safe bounds
check annotations. C oncurrency an d Com putation: P ractice and E x
p erien ce , . 21, . 1 (2009).
[59] Wadler, P. Proofs are programs: 19th century logic and 21st century
computing. Dr. D obbs J ou rn al ( 2000).
[60] Wegner, P. technique for counting ones in a binary computer.
C om m unications o fth e A C M , . 3, . 5 (1960), . 322.
[61] Xu, D. N., Peyton Jones, S., Claessen, K. Static contract checking
for Haskell. SIG P L A N N otices, . 44, . 1 (2009), . 41-52.

1 ., .
++. - , 2008.

$ , , 4 1 , 6 2 , 1 3 2 , 13 4 , 146
$, , 458
, ( ), , 9 6 , 4 6 6
. ( - ), 61
. ( ), , 8 4
; ( ), 3 4
{} ( ), 3 4
... ( ), 2 0 3
+, , 4 5 0
+, , 9 0
+, , 4 4 5
+, , 8 8
+ + , , 8 4 , 4 4 5 , 4 4 7
++, , 87
-, , 4 5 0
-, , 8 8
-, , 4 4 5
--, , 4 4 5 , 4 4 7
" , , 87
*, , 4 5 0
*, , 8 7 ,1 6 4
*, , 8 9
*, , 4 4 5
/, , 4 5 0
/, , 8 9
&, , 450
& , , 87, 9 4 , 164
& , , 4 6 6
& & , , 9 4 , 4 6 6
% , , 4 5 0
% , ,
33
% , , 8 9
^, , 9 4
^^, , 8 9
1, , 79 , 8 8
1 ( > ), 3 9
1=, , 9 2 ,1 5 4 , 2 6 1 , 4 5 3
?:, , 4 6 6
?:, , 72

, , 450
, , 94
|, , 9 4 , 4 6 6
= , , 95
= = , , 92, 148, 154, 261, 453
< , , 93, 265, 453
, , 450
, , 90
<=, , 93, 265, 453
>, , 93, 26 5 , 453
, , 450
, , 9 0
> = , , 93, 265, 453
> , , 90
- , , 90
-, , 450
- , , 5 2 , 9 0 , 149,
161
-, , 87
-, , 445
- = , , l4o, 141

0x, , 65
0X , , 65

a b s t r a c t, , 274
A c tiv e T e m p la te L ib r a r y (A T L ), 195
a lia s , , 1 9 0 , 3 3 8
a lia s , , 1 91, 194
a lia s t h i s , , 3 2 5
a lig n o f , , 3 3 1
a lig n , , 3 3 0
A S C II, , 1 5 6 , 157, 158
asm , , 125, 470
a s s e rt, , 80
A s s e r tE r r o r , , 8 0
A s s e r tE r r o r , , 3 6 6 , 3 7 9
a s s e r t( f a ls e ) , , 39 1
a .s t a r ts W i t h ( b ) , , 4 5

524
A S T - , 3 4 5
a u to , , 1 45, 148

B a s ic M u l tilin g u a l P la n e , B M P , 159
b itf ie ld s , , 81
B O M ( b y te o r d e r m a r k ) , , 4 0 2
b o o l, , 6 0
b r e a k , , 114
byK ey, ,
155
b y L in e , , 4 6
b y te , , 3 2 , 6 0
b y V a lu e , ,
155

D SEL, ,
81
d s t r i n g , , 72, 160
d u p , , 3 8 ,1 3 1 , 148

E
e ls e , i f , 103
e ls e , s t a ti c if, 106
e m p ty , , 4 5 9
E r r o r , , 379
E x c e p tio n , , 3 6 5 , 3 6 6
E x c e p tio n , , 491
e x p a n d , T u p le , 2 0 8
e x p o r t, , 2 5 6 , 322
e x p , , 218
e x te r n , , 4 2 5

c, , 72
C 9 9 , , 61
c a s , , 511
c a s 2 , , 511
c a s e , , 106
c a s t, , 5 3 , 8 8
c a tc h , , 118
c h a r , , 4 6 , 6 0 , 1 60
, 160
c la s s , , 4 4
c le a r , , 2 3 8 , 315
c o n s t, , 176, 3 4 9 , 3 5 9 ,
360
c o n tin u e ,
, 37, 114
c o re .m e m o ry , , 2 3 8
c o re , , 4 3 0
c o s, , 2 1 8

% f, 3 3
f a c to r y , , 52
f a c to r y , , 2 6 6
f a ls e , , 6 0 , 62
F ile , , 373
fin a lly , , 118, 3 6 9
f i n a l s w itc h , , 108
f i n a l , , 252
f in d , , 47
f lo a t, , 3 2 , 6 0
fo r, , 4 5 9
fo re a c h , , 155, 4 5 9
fo re a c h , , 31, 34
fro n t, , 459
f u n c tio n , , 74, 191, 192
f, , 6 4
F, , 6 4

.d , , 4 0 2
d , , 72
D B C S - D o u b le B y te C h a r a c te r S e t, 4 1 0
d c h a r , , 6 0 , 16 0
, 16 0
-d e b u g , , 4 2 9
debug, , 429
d e f a u l t, , 107
d e le g a te , , 74, 8 4 , 192
d e p r e c a te d , , 4 2 7
.d i, , 4 0 2
@ d is a b le , , 3 2 6
D o m a in - S p e c if ic E m b e d d e d L a n g u a g e ,
D SEL , 467
d o u b le , , 3 2 , 6 0
d o -w h ile , , 1 0 9

G C .fre e (), , 2 3 8
g e t, , 153
g o to , , 4 5 , 114

I
-I, , 4 0 5
% id , , 3 3
IE E E 7 5 4 , , 6 5
if , , 102
if , , 34
if , , 182
im m u ta b le , ,
, 3 2 , 70, 160, 3 5 0 , 481

525

import, , 30
#include
++, 30
import Python,
30
import, , 70
#include ,
70
in, , 450
in, , 36, 175
in, , 37, 91, 153
, 37
in, , 382
lin, , 91
init, , 232
inout, , 362
interface, , 268
int, , 32, 60
is, , 82, 93, 148, 154, 466
!is, , 93

keys, ,
155

L
L, , 63, 64
length, , 132, 143,146
-lib, , 418
ln, , 31
long, , 32, 60
1-, 75,174, 175

main, , 29, 31, 139,173


, 29, 140
, 52
-main, rdmd, 173
MessageMismatch, , 482
Message Passing Interface, MPI, 478
message, PriorityMessageException,
491
MFC, , 195
mixin, , 81, 338, 446, 467
mixin, , , 120
module, , 260
module, , 414
move, , 313

N
NaN, , 47
new, , 226

new, , 84, 86
Non-Virtual Interface, NVI, 270, 399
nothrow, , 217
nothrow, , 370
null, , 47, 62, 131,152
NVI, 270, 399

object.opEquals(a, b), , 454


Object, , 52, 260
object, , 238, 261, 454
-of, , 418
offsetof, , 330
opApply, , 460
opAssign, , 454
opAssign, , 318
opBinaryRight, , 452
opCast, , 448
opCmp, , 265
opCmp, , 156
opCmp, , 318
opCmp, object, 265
opDispatch, , 463
opDollar, , 458
opEquals, , 261
opEquals, , 318, 320
opEquals, object, 261
opHash, , 152
opIndex, , 456
opOpAssign, , 455
opUnary, , 445
outer, , 279
out, , 36, 176
ref, 36
out, , 384
override, , 245
OwnerFailed, , 490
OwnerTerminated, ,
4 8 8 - 490

P
package, , 255,
322
Phobos, , 429
popFront(), , 459
pow, , 35, 89
, 35
PriorityMessageException,
, 491
prioritySend, , 491
private state ( ), 217
private, , 47, 178
private, , 255, 322

526
@ p r o p e r ty , , 8 4
@ p r o p e r ty , , 1 99
p r o te c te d , , 2 5 5
p tr, , 37
p u b lic , , 2 5 6 , 3 2 2
p u b lic im p o r t ,
, 409
p u r e , , 215

R
R A II, 373
R a n g e E rro r, , 85
r a n g e ( ), 172
rd m d , , 30
re a d f, , 53
r e a l, , 3 2 , 6 0 , 4 9 6
re c e iv e O n ly , , 4 8 2 , 4 8 9
r e c e iv e T im e o u t, , 4 8 5
re c e iv e , , 4 8 3 , 4 8 9 , 491
re d u c e , , 202
r e f , , 3 5 , 127, 131, 147, 151,
174, 175, 176, 178
, 35, 38
re f, , 2 0 0 , 305
re g e x , , 48
, 48
-re le a s e , , 8 0 , 1 3 4 , 3 8 9
rem o v e, ,
154
r e t u r n , , 117
- , 7 5 , 175

s
% s, , 33
@ s a fe , , 1 3 3 , 4 2 1 , 4 7 0
- s a fe , , 4 2 2
S a fe D , 1 6 6 , 4 2 1
s c o p e , , 123
sc o p e (e x it), , 121
, 121
s c o p e (f a ilu re ) , , 1 24
s c o p e (s u c c e s s ), , 1 2 3
sen d , , 482
s e tO w n e r, , 4 8 8
s h a re d , , 3 50, 477,
4 9 3 ,5 0 2
sh eb an g , , 30
sh o rt, , 32, 60
s in , , 2 1 8
.s iz e o f , , 3 3 9
s iz e _ t, , 3 3 8
s lic in g ,
, 57

s p a w n , , 4 79
s p lit, , 47
S t a n d a r d T e m p la te L ib ra r y , S T L , 4 3 0
s t a ti c , , 144, 178, 194
s t a ti c , , 2 8 2
s t a t i c if , , 104
s t a t i c i m p o r t,
, 410
s t a t i c t h is ( ) , , 4 2 3
s t a t i c th is ( ) , ,
242
s t a ti c - t h is ( ) , ,
243
s t d .a l g o r it h m , , 4 5 , 20 1 , 2 0 2 , 2 2 8 ,
313, 430
s t d .a r r a y , , 4 3 0
s t d .b ig i n t , , 4 3 0
s t d .b itm a n ip , , 4 3 0
s td .c o n c u r r e n c y , , 4 3 0 , 4 9 4 , 4 9 6
s td .c o n ta in e r , , 4 3 0
s td .c o n tr a c ts s td .e x c e p tio n , , 3 9 0
s td .c o n v .te x t, , 381
s td .c o n v .to , , 3 5 8
s td .c o n v , , 140, 3 3 8 , 4 3 0
s t d .d a t e t i m e , , 4 3 0
s t d .f il e , , 4 3 0
s td .f u n c t io n a l , , 4 3 0
s t d .g e t o p t, , 431
s td .js o n , , 4 31
s t d .m a th , , 3 7 9 , 431
s td .n u m e r ic , , 431
s t d .p a t h , , 431
s t d .r a n d o m , , 131, 2 2 4 , 4 31
s t d .r a n g e , , 2 0 2 , 431
s td .r e g e x , , 4 5 , 431
s t d .s t d io , , 3 7 3 , 431
s t d . s t r i n g , , 431
s t d . t r a i t s , , 431
s td .ty p e c o n s , , 431
s t d . u t f , , 162, 43 1
s t d .v a r i a n t , , 4 3 1 , 4 8 6
std , , 430
s t r i d e , , 162
s trin g o f, , 207
s t r i n g , , 37, 4 6 , 70, 72, 160
, 47
, 46
s tru c t, , 44
s u p e r , , 62
s u p e r, ,
248
sw a p , , 2 2 8
s w itc h , , 106
s y n c h r o n iz e d , , 5 0 2

527

s y n c h ro n iz e d , , 5 0 2
s y n c h ro n iz e d , , 5 0 9
@ sy ste m , , 1 3 3 , 4 2 1
T
te m p la te , , 3 4 1
t h is , , 62
t h is , , 2 3 2 , 3 0 6
- th is ( ) , , 23 7 , 313
th is (th is ) , ,
307
T h re a d ID , 4 8 2
T h re a d -L o c a l S to r a g e , T L S , 4 7 7
T h ro w a b le , , 118, 3 6 6
th ro w , , 118
T id , , 4 8 2
to H a s h , , 261
to H a s h , , 156
to lo w er, , 47
to S tr in g , , 2 6 0
to , , 140, 3 3 8
, 46
t r a n s it o r y s t a te ( ),
217
t r u e , , 6 0 , 62
@ tr u s te d , , 1 3 3 , 4 2 1 , 4 2 2
t r y , , 118
tu p le ( ), 2 0 5
T u p le , , 2 0 8
tu p le , , 2 0 8
ty p e id , , 6 2
ty p e id , , 70, 4 6 6
ty p e o f(n u ll), , 59 , 6 0
ty p e o f, , 7 0 ,1 8 3 , 3 3 9

u b y te , , 3 2 , 6 0 , 160
U C S -2, , 159
u in t, , 3 2 , 6 0 , 160
u lo n g , , 3 2 , 6 0
u n ifo rm , , 131
u n i tt e s t , , 4 0 , 173
- u n itte s t, , 173
U N IX , 30
u s h o r t, , 3 2 , 6 0 , 160
U T F -8, , 1 5 6 ,1 5 8
, 160
, 1 60
, 158
U T F-16, , 1 5 6 ,1 5 9
, 159
, 15 9 , 1 6 0 , 164
, 159

, 159
, 159
U T F -3 2 , , 1 5 6 ,1 6 0
, 160
, 1 60
U tf E x c e p tio n , , 3 9 2
U T F , , 160
U /u , , 6 3
V
v a lu e s ,
, 155
V a r ia n t, , 4 8 6
-v e rb o s e , , 4 0 6
v e r s io n , , 4 2 7
- v e rs io n , , 4 2 8
v o id , , 145,
236
v o id , , 5 9 , 6 0

w
w, , 72
-w, , 4 2 7
w c h a r, , 6 0 , 160
, 160
w h ile , , 1 0 9
w ith , , 116
w r ite ln , , 3 1 , 3 3 , 2 0 3
, 31, 33
, 33
w s tr in g , , 72 , 1 6 0
W Y S IW Y G - , 67, 6 8

, 296
, 334
, 294
, 266
, 473
, , 199

, 245
, 95, 336
, 496
, 469
D , 2 2 4
, 4 1 8
, 419
, 419

, 419

528

, 420
, 52, 53,
81,87
, 235

, 159
, 119
, 473
, 403
alias, 413
, 411
, 409
, 412
, 410
, 411
, 193
, 311
, 460
, 305
, 431
x86, 432
x 8 6 -6 4 ,435
, 371
, 179
, 511
, 199

++, 224

, 470, 499
, \ 68

, 298
, 241, 294
, 425
, 237
D, 172, 201,430
, 201
, 44
, 247
, 266
, 424
,
101
, 245

, 179

3
, 196
, 61

backspace, 67
, 67
, 67
, 67
, 67
, 67
, 67
, 67
, 67
UTF-8, 67
UTF-16, 67
UTF-32, 67
, 67
,, 56, 229

, 61
, 61
, 61
, 482
, 379
, 87
, 254, 310
, 200, 416

alias, 338
return, , 117
with, , 116
, 116

try-catch-finally, 119
,
115
, 114,115

, 103
, 102
, 37, 103
, 104,105
, 101
, 101


,108
, 108
, 106
, 106
, 106
, 108, 109

, , 37
, 101

, 31, 34, 37, 38, 110, 111,


112

, 109
, 109
, 109
while do-while, 109
, 51, 268
, 274
, 272
, 269
, 268
, , 51
, 364
, 370, 371
, 371
, 117, 364
, 97

, 70, 349
const, 349, 360
immutable, 350
, 351
, 353
, 351
shared, 350
, 494

, 361
, 494
, 51, 225
, 54, 274, 275
, 54
, 278
, 278, 279
, 323
, 280, 281, 282
, 281
, 331

, 244
, 243
, 55
, 232
, 236

,
233

, 283

529
, 54, 232
, 233
, 356
, 233
, 233
, 54
, 242, 243
, 260

, 275
, 354
, 251, 252, 253
, 244, 283
, 246
, 248
, 245, 248, 249
, 245
, 246
(), 246
, 283
, 245

, 302
, 301
, 226
, 226
, 290
, 292
, 51
, 510
, 329

Object.factory, 52
, 251
, 260
, 253

, 261, 262, 263


, 226, 231, 232, 266
, 265
, 261
, 35, 178
, 250
, 156, 157
, 156
, 158, 163
, 424

, 30
, 52
, 218
, , 43
, 32
, , 32

530
, 232
this(this),
303,307

mixin template, 345


, 347
, 427
, 428
, 428
, 428
, 429

, 343
, 339

foreach, 459, 460


,459
, 131, 459
, 314

, , 56
, , 56
, 161
, 118
, 205
, 497

, 171
, 253

, 63
, , 66
, 208
, 192
, 62
, 131, 144, 145
, 152
, 64
, 64
, 65
, 65
, 65
, 65
, 65
, 67, 162
, 71
,70
, 69
, 67
, 191, 192
, 191
, 192

, 63
, 63
, 63
, 63
, 63
, 101
, 189
-, 73, 191
, 74

, , 139
, 70
, 505
, 236
, 402
,
201
, 32
, 401
, 133
, 423
, 133
, 423
, 133
, 239, 497


, 93

, 165
, 281
, 80
, 195
, 76
, 159
, , 87

, 469, 478
, 195
, 199
, 105
, 404
, 182, 446

, , 186
, 32
, 51
, 84

, 33

, 33
, 33
, 391
, 34

, 185
, 328
, 292

, 401

, 377
, 379, 385, 388
,378, 396, 398
, 379, 384
, 379, 382
, 378, 381

, 180
-
, 225
, 251, 254, 255, 256,
257
, 244
, 254
,
170
, 469
, 473

, 503
, 504

, 484
, 482, 491
, 473
, 474
, 469
, 469, 473
, 480
, 479
, 482
, 481
, 488
-, 488
, 469, 473
, 470
, 496
, 470
, 501
, 470

531
, 470, 497
, 470
, 481
,
496

, 497
, 499
,501
, 470
, 470
, 497
, 470
, 511
-, 190
, 200
, 371
, 80
, 367

$ ,4 5 8
foreach, 459
, 460
,
450
, 449
,
456

, 454
, 458
,
451

,449
, 445


, 447
, 445
, 101
,
, 60
, 33
, 245
, 347
, 364
, 286
, 287
, 288
, 379
, 473
, 47
, 484

532
, 54
, 190
, 379
, , 34
-, 101
, 227
,
394

, 50
, 53
/,
50,267

, 35
, 53, 101
, 473
, 70, 327
, 199
, 102

P
, 92
, 136
, 71
, 334
, ,
201
, 457
, 161
, 373
, 395
, 415

, 41
, 245

, 133
, 133
, 87, 237
, 228
, , 239
, 199
, 56
, 56
, 267
, 182
, 61
, 465
, 470
, 142

, 110
, 445
, 246
, 136
, 437
x86, 438
cdecl, 438
fastcall, 439
pascal, 439
stdcall, 439
thiscall, 439
D, 439
x86-64, 440
AMD64 ABI, 440
Microsoft x64, 440
, 85
, 239
, 254, 457
, 34
D , 255
, 32, 33, 56, 70, 104, 140,178, 194,
428
C#, 32, 270, 283, 341
++, 33, 44, 56, 253, 270, 283, 293,
311, 341, 408
++, 107
Eiffel, 283
Java, 32, 40, 53, 253, 261, 270, 283,
341
Perl 6, 93
Python, 93, 408
- , 35
, 43
-3, 421
- ,
57
, 71
, 29
, 57
,
53
, 511
, 56
, 39, 81, 89,162,
422,429
, 430
, 50
, 178
, 242
, 247
, 463
, 34

, 34

, 34
, 34

-, 50
, 50
, 265
, 69
, 68
, , 354
, 139
, 245
, 95
, 159
, 159
, 227

T
, 95
, 40
, 317
, 317

null, 59
, 59
, 443
, 201
, 201

STL, 201
,
201
, 60
, 60

, 237
, 237
, 308
, 208
, 208
, 60
, 72
length, , 37
, 37, 73, 151- 155,
169, 265, 462
, 3 7 ,130- 132, 134,
135, 137- 141, 144, 167
, 150
, 37
, 84
, 38
, 145,149
, 47
, 37

533
, 38
, 39, 41, 85
, 72
, 38
, 144, 146,
147,148, 149, 168
, 36
, 331
, 333
, 332
, 332
, 60
, 334
, 336
, 246
, 156, 443
, 60
D, 59
, 32, 47, 60
, 47
, 44
, 57
,156
, 44, 57, 302
, 323, 324
, 311
, 321, 322
, 314
, 328, 331
, 315
,
47
, 306, 316
, 303,311
, 317
, 302
, 313
, 326
, 304
, 306, 307
, 44, 46
, 318
, 315
, 330
, 320
, 313, 316
,246
-, 44, 57
, 32, 60
, 47
, 60
, 79
, 171, 173
, , 101

534

, 501, 509

,
33, 203
, 205
, 209
, 203, 204
, 185
, 186
, 186
, 214
, 216, 217

, 408

, 164
, 192
, 511
, 102
, 378
, 391

, 29
, 343
, 35
, 36, 191

lazy, 177
, 35
, 84
, 214
, 193
, 193
, 193
, 36
, 73, 190,194
, 201

, 194, 195, 196


, 192
-, 36, 43, 191
, 42
, 181, 182
, 35
in, 175
out, 176
, 354
-, 190, 191
, 179
, 171, 173, 174
, 183
, 188,189, 408
, 189
, 189
, 36
, 199
, 354

, 39
, 39
Java, C# ++, 40
, 36

X
-, 298
-, 36, 37
, 256

,
, 473
, , 424
, 163

, 185, 265

mixin, 345

, 227

, , 156
,
159
5.1, 157
, 157
, 156
, 158
, 156,157
, 157

, 138

Ql.

++
560 a p .,




Qt.
,
+
*, ,

.
, Qt 4-6.
,
Windows, OS X Linux Qt 4.6
( Qt 4.5)
Qt.


,

480 .,

,
, , wiki-
-, -
,
,
,
- .
,
-: , ,
. . Java
,
- , -
.

,
,
.

"-"
1995 e 9

- .
-
,
.
: OReilly, Pearson Education, NewRlders,
Addison Wesley, Wiley, McGraw-Hill, N0 Starch Press, Packt, Dorset
House, Apress .


, , .
:
- :

. 0 . 16 , . 7 (. ),
. (812) 380-5007
:

. 2- , . 14
(. /),
. (495) 638-5305

http://www.symbol.ru

w uv w . s m b I . r u

,
.
, , www.symbol.ru.

. !



+ + ,

+ + .

++:


++

.
,
,
,
, .
2 0 0 6
-
D ,
.
D

D.
D.

: _________

4UiRTErfEU:

D-

.
,

(, -,
),
, ,
.
D,
. -
,
. ,
, , ,
D. :




,
,
,
,

, -
,
D
,
-
,
D, .

|
tf-

ipizpaM M upoiaiue

++
,
U


ISBN 978-5-93286-205-6

www.symbol.ru
-
(812) 380-5007, (495) 638-5305

9 785932

862056