@@ -4,209 +4,45 @@ $(D_S Type Qualifiers,
4
4
5
5
$(HEADERNAV_TOC)
6
6
7
- $(P Type qualifiers modify a type by applying a $(GLINK2 declaration, TypeCtor).
8
- $(I TypeCtor)s are: $(D const), $(D immutable), $(D shared), and $(D inout).
9
- Each applies transitively to all subtypes.
7
+ $(P $(I Type qualifiers) are a subset of $(I type constructors).
8
+ Type qualifiers are: $(D const), $(D immutable), $(D shared), and $(D inout).
9
+ Types resulting from the application of type qualifiers to a type
10
+ are called $(I qualified types).
10
11
)
11
12
12
- $(H2 $(LNAME2 const_and_immutable, Const and Immutable ))
13
+ $(H2 $(LNAME2 transitive, Transitivity ))
13
14
14
- $(P When examining a data structure or interface, it is very
15
- helpful to be able to easily tell which data can be expected to not
16
- change, which data might change, and who may change that data.
17
- This is done with the aid of the language typing system.
18
- Data can be marked as const or immutable, with the default being
19
- changeable (or $(I mutable)).
15
+ $(P Type qualifiers apply transitively to all subtypes.
16
+ It is not possible to specify, for example, a const pointer
17
+ to a mutable type.
20
18
)
21
19
22
- $(P $(D immutable) applies to data that cannot change.
23
- Immutable data values, once constructed, remain the same for
24
- the duration of the program's
25
- execution.
26
- Immutable data can be placed in ROM (Read Only Memory) or in
27
- memory pages marked by the hardware as read only.
28
- Since immutable data does not change, it enables many opportunities
29
- for program optimization, and has applications in functional
30
- style programming.
20
+ $(P Types are $(I mutable) by default, meaning variables with such
21
+ types can be assigned new values at any time.
31
22
)
32
23
33
- $(P $(D const) applies to data that cannot be changed by
34
- the const reference to that data. It may, however, be changed
35
- by another reference to that same data.
36
- Const finds applications in passing data through interfaces
37
- that promise not to modify them.
38
- )
39
-
40
- $(P Both immutable and const are $(I transitive), which means
41
- that any data reachable through an immutable reference is also
42
- immutable, and likewise for const.
24
+ $(P Types are thread local by default, meaning variables with such
25
+ types are not accessible from other threads.
43
26
)
44
27
45
- $(H2 $(LNAME2 immutable_storage_class, Immutable Storage Class))
46
-
47
- $(P
48
- The simplest immutable declarations use it as a storage class.
49
- It can be used to declare manifest constants.
50
- )
51
-
52
- ---
53
- immutable int x = 3; // x is set to 3
54
- x = 4; // error, x is immutable
55
- char[x] s; // s is an array of 3 char's
56
- ---
57
-
58
- $(P The type can be inferred from the initializer:
59
- )
60
- ---
61
- immutable y = 4; // y is of type int
62
- y = 5; // error, y is immutable
63
- ---
64
-
65
- $(P If the initializer is not present, the immutable can
66
- be initialized from the corresponding constructor:
28
+ $(BEST_PRACTICE Initially, the transitivity can appear onerous.
29
+ But once successfully used, it enables much clearer specifications of
30
+ types, and is foundational for programming in a functional style.
67
31
)
68
32
69
- ---
70
- immutable int z;
71
- void test()
72
- {
73
- z = 3; // error, z is immutable
74
- }
75
- static this()
76
- {
77
- z = 3; // ok, can set immutable that doesn't
78
- // have static initializer
79
- }
80
- ---
81
- $(P
82
- The initializer for a non-local immutable declaration must be
83
- evaluatable
84
- at compile time:
85
- )
86
33
87
- ---
88
- int foo(int f) { return f * 3; }
89
- int i = 5;
90
- immutable x = 3 * 4; // ok, 12
91
- immutable y = i + 1; // error, cannot evaluate at compile time
92
- immutable z = foo(2) + 1; // ok, foo(2) can be evaluated at compile time, 7
93
- ---
34
+ $(H2 $(LNAME2 immutable_type, Immutable Type))
94
35
95
- $(P The initializer for a non-static local immutable declaration
96
- is evaluated at run time:
36
+ $(P $(D immutable) applies to data that cannot change.
37
+ Immutable data values, once constructed, remain the same for
38
+ the duration of the program's
39
+ execution.
40
+ Immutable data can be placed in ROM (Read Only Memory) or in
41
+ memory pages marked by the hardware as read only.
97
42
)
98
- ---
99
- int foo(int f)
100
- {
101
- immutable x = f + 1; // evaluated at run time
102
- x = 3; // error, x is immutable
103
- }
104
- ---
105
43
106
- $(P
107
- Because immutable is transitive, data referred to by an immutable is
108
- also immutable:
109
- )
110
-
111
- ---
112
- immutable char[] s = "foo";
113
- s[0] = 'a'; // error, s refers to immutable data
114
- s = "bar"; // error, s is immutable
115
- ---
116
-
117
- $(P Immutable declarations can appear as lvalues, i.e. they can
118
- have their address taken, and occupy storage.
119
- )
120
-
121
- $(H2 $(LNAME2 const_storage_class, Const Storage Class))
122
-
123
- $(P
124
- A const declaration is exactly like an immutable declaration,
125
- with the following differences:
126
- )
127
-
128
- $(UL
129
- $(LI Any data referenced by the const declaration cannot be
130
- changed from the const declaration, but it might be changed
131
- by other references to the same data.)
132
-
133
- $(LI The type of a const declaration is itself const.)
134
- )
135
-
136
- $(COMMENT
137
- $(TABLE
138
-
139
- $(TR $(TH $(NBSP)) $(TH AddrOf) $(TH CTFEInit) $(TH Static) $(TH Field) $(TH Stack) $(TH Ctor))
140
-
141
- $(TR $(TD $(NBSP))
142
- $(TD Can the address be taken?)
143
- $(TD Is compile time function evaluation done on the initializer?)
144
- $(TD allocated as static data?)
145
- $(TD allocated as a per-instance field?)
146
- $(TD allocated on the stack?)
147
- $(TD Can the variable be assigned to in a constructor?)
148
- )
149
-
150
-
151
- $(TR $(TH Global data))
152
-
153
- $(TR $(TD1 const T x;) $(Y) $(N) $(Y) $(N) $(N) $(Y))
154
- $(TR $(TD1 const T x = 3;) $(N) $(Y) $(N) $(N) $(N) $(N))
155
- $(TR $(TD1 static const T x;) $(Y) $(N) $(Y) $(N) $(N) $(Y))
156
- $(TR $(TD1 static const T x = 3;) $(Y) $(Y) $(Y) $(N) $(N) $(N))
157
-
158
-
159
- $(TR $(TH Class Members))
160
-
161
- $(TR $(TD1 const T x;) $(Y) $(N) $(N) $(Y) $(N) $(Y))
162
- $(TR $(TD1 const T x = 3;) $(N) $(Y) $(N) $(N) $(N) $(N))
163
- $(TR $(TD1 static const T x;) $(Y) $(N) $(Y) $(N) $(N) $(Y))
164
- $(TR $(TD1 static const T x = 3;) $(Y) $(Y) $(Y) $(N) $(N) $(N))
165
-
166
-
167
- $(TR $(TH Local Variables))
168
-
169
- $(TR $(TD1 const T x;) $(Y) $(Y) $(N) $(N) $(Y) $(N))
170
- $(TR $(TD1 const T x = 3;) $(Y) $(N) $(N) $(N) $(Y) $(N))
171
- $(TR $(TD1 static const T x;) $(Y) $(Y) $(Y) $(N) $(N) $(N))
172
- $(TR $(TD1 static const T x = 3;) $(Y) $(Y) $(Y) $(N) $(N) $(N))
173
-
174
- $(TR $(TH Function Parameters))
175
-
176
- $(TR $(TD1 const T x;) $(Y) $(N) $(N) $(N) $(Y) $(N))
177
- )
178
-
179
-
180
- $(P Notes:)
181
-
182
- $(OL
183
- $(LI If CTFEInit is true, then the initializer can also be used for
184
- constant folding.)
185
- )
186
-
187
-
188
- $(TABLE
189
- <caption>Template Argument Deduced Type</caption>
190
- $(TR $(TH $(NBSP)) $(TH mutable $(CODE T)) $(TH1 const(T)) $(TH1 immutable(T)))
191
- $(TR $(TD1 foo(U)) $(TDE T) $(TDE T) $(TDE T))
192
- $(TR $(TD1 foo(U:U)) $(TDE T) $(TDE const(T)) $(TDE immutable(T)))
193
- $(TR $(TD1 foo(U:const(U))) $(TDI T) $(TDE T) $(TDI T))
194
- $(TR $(TD1 foo(U:immutable(U))) $(NM) $(NM) $(TDE T))
195
- )
196
-
197
- $(P Where:)
198
-
199
- $(TABLE
200
- $(TR $(TD $(GREEN green)) $(TD exact match))
201
- $(TR $(TD $(ORANGE orange)) $(TD implicit conversion))
202
- )
203
- )
204
-
205
- $(H2 $(LNAME2 immutable_type, Immutable Type))
206
-
207
- $(P
208
- Data that will never change its value can be typed as immutable.
209
- The immutable keyword can be used as a $(I type qualifier):
44
+ $(P Immutable data is implicitly safe to access from multiple
45
+ threads without synchronization.
210
46
)
211
47
212
48
---
@@ -247,7 +83,7 @@ immutable(int) y = 3; // y is immutable
247
83
---
248
84
249
85
250
- $(H2 $(LNAME2 creating_immutable_data, Creating Immutable Data))
86
+ $(H3 $(LNAME2 creating_immutable_data, Creating Immutable Data))
251
87
252
88
$(P
253
89
The first way is to use a literal that is already immutable,
@@ -282,7 +118,7 @@ auto p = s.idup;
282
118
p[0] = ...; // error, p[] is immutable
283
119
---
284
120
285
- $(H2 $(LNAME2 removing_with_cast, Removing Immutable or Const with a Cast))
121
+ $(H3 $(LNAME2 removing_with_cast, Removing Immutable or Const with a Cast))
286
122
287
123
$(P
288
124
An immutable or const type qualifier can be removed with a cast:
@@ -328,7 +164,7 @@ void main()
328
164
}
329
165
---
330
166
331
- $(H2 $(LNAME2 immutable_member_functions, Immutable Member Functions))
167
+ $(H3 $(LNAME2 immutable_member_functions, Immutable Member Functions))
332
168
333
169
$(P
334
170
Immutable member functions are guaranteed that the object
@@ -384,14 +220,12 @@ struct S
384
220
385
221
$(H2 $(LNAME2 const_type, Const Type))
386
222
387
- $(P
388
- Const types are like immutable types, except that const
389
- forms a read-only $(I view) of data. Other aliases to that
390
- same data may change it at any time.
223
+ $(P $(D const) applies to data that cannot be changed by
224
+ the const reference to that data. It may, however, be changed
225
+ by another reference to that same data.
391
226
)
392
227
393
-
394
- $(H2 $(LNAME2 const_member_functions, Const Member Functions))
228
+ $(H3 $(LNAME2 const_member_functions, Const Member Functions))
395
229
396
230
$(P
397
231
Const member functions are functions that are not allowed to
@@ -515,6 +349,97 @@ void main()
515
349
and the correctness of it must be verified by the user.
516
350
)
517
351
352
+ $(H2 $(LNAME2 immutable_storage_class, Immutable Storage Class))
353
+
354
+ $(P
355
+ The simplest immutable declarations use it as a storage class.
356
+ It can be used to declare manifest constants.
357
+ )
358
+
359
+ ---
360
+ immutable int x = 3; // x is set to 3
361
+ x = 4; // error, x is immutable
362
+ char[x] s; // s is an array of 3 char's
363
+ ---
364
+
365
+ $(P The type can be inferred from the initializer:
366
+ )
367
+ ---
368
+ immutable y = 4; // y is of type int
369
+ y = 5; // error, y is immutable
370
+ ---
371
+
372
+ $(P If the initializer is not present, the immutable can
373
+ be initialized from the corresponding constructor:
374
+ )
375
+
376
+ ---
377
+ immutable int z;
378
+ void test()
379
+ {
380
+ z = 3; // error, z is immutable
381
+ }
382
+ static this()
383
+ {
384
+ z = 3; // ok, can set immutable that doesn't
385
+ // have static initializer
386
+ }
387
+ ---
388
+ $(P
389
+ The initializer for a non-local immutable declaration must be
390
+ evaluatable
391
+ at compile time:
392
+ )
393
+
394
+ ---
395
+ int foo(int f) { return f * 3; }
396
+ int i = 5;
397
+ immutable x = 3 * 4; // ok, 12
398
+ immutable y = i + 1; // error, cannot evaluate at compile time
399
+ immutable z = foo(2) + 1; // ok, foo(2) can be evaluated at compile time, 7
400
+ ---
401
+
402
+ $(P The initializer for a non-static local immutable declaration
403
+ is evaluated at run time:
404
+ )
405
+ ---
406
+ int foo(int f)
407
+ {
408
+ immutable x = f + 1; // evaluated at run time
409
+ x = 3; // error, x is immutable
410
+ }
411
+ ---
412
+
413
+ $(P
414
+ Because immutable is transitive, data referred to by an immutable is
415
+ also immutable:
416
+ )
417
+
418
+ ---
419
+ immutable char[] s = "foo";
420
+ s[0] = 'a'; // error, s refers to immutable data
421
+ s = "bar"; // error, s is immutable
422
+ ---
423
+
424
+ $(P Immutable declarations can appear as lvalues, i.e. they can
425
+ have their address taken, and occupy storage.
426
+ )
427
+
428
+ $(H2 $(LNAME2 const_storage_class, Const Storage Class))
429
+
430
+ $(P
431
+ A const declaration is exactly like an immutable declaration,
432
+ with the following differences:
433
+ )
434
+
435
+ $(UL
436
+ $(LI Any data referenced by the const declaration cannot be
437
+ changed from the const declaration, but it might be changed
438
+ by other references to the same data.)
439
+
440
+ $(LI The type of a const declaration is itself const.)
441
+ )
442
+
518
443
$(SPEC_SUBNAV_PREV_NEXT enum, Enums, function, Functions)
519
444
)
520
445
0 commit comments