Changeset 1242 for trunk/docsrc/const3.dd
- Timestamp:
- 07/16/09 18:24:08 (3 years ago)
- Files:
-
- trunk/docsrc/const3.dd (modified) (24 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/docsrc/const3.dd
r863 r1242 1 1 Ddoc 2 2 3 $(D_S Const and I nvariant,3 $(D_S Const and Immutable, 4 4 5 5 $(P When examining a data structure or interface, it is very … … 7 7 change, which data might change, and who may change that data. 8 8 This is done with the aid of the language typing system. 9 Data can be marked as const or i nvariant, with the default being9 Data can be marked as const or immutable, with the default being 10 10 changeable (or $(I mutable)). 11 11 ) 12 12 13 $(P $(I i nvariant) applies to data that cannot change.14 I nvariantdata values, once constructed, remain the same for13 $(P $(I immutable) applies to data that cannot change. 14 Immutable data values, once constructed, remain the same for 15 15 the duration of the program's 16 16 execution. 17 I nvariantdata can be placed in ROM (Read Only Memory) or in17 Immutable data can be placed in ROM (Read Only Memory) or in 18 18 memory pages marked by the hardware as read only. 19 Since i nvariantdata does not change, it enables many opportunities19 Since immutable data does not change, it enables many opportunities 20 20 for program optimization, and has applications in functional 21 21 style programming. … … 29 29 ) 30 30 31 $(P Both i nvariantand const are $(I transitive), which means32 that any data reachable through an i nvariantreference is also33 i nvariant, and likewise for const.34 ) 35 36 $(SECTION2 I nvariantStorage Class,37 38 $(P 39 The simplest i nvariantdeclarations use it as a storage class.31 $(P Both immutable and const are $(I transitive), which means 32 that any data reachable through an immutable reference is also 33 immutable, and likewise for const. 34 ) 35 36 $(SECTION2 Immutable Storage Class, 37 38 $(P 39 The simplest immutable declarations use it as a storage class. 40 40 It can be used to declare manifest constants. 41 41 ) 42 42 43 43 --- 44 i nvariantint x = 3; // x is set to 345 x = 4; // error, x is i nvariant44 immutable int x = 3; // x is set to 3 45 x = 4; // error, x is immutable 46 46 char[x] s; // s is an array of 3 char's 47 47 --- … … 50 50 ) 51 51 --- 52 i nvarianty = 4; // y is of type int53 y = 5; // error, y is i nvariant54 --- 55 56 $(P If the initializer is not present, the i nvariantcan52 immutable y = 4; // y is of type int 53 y = 5; // error, y is immutable 54 --- 55 56 $(P If the initializer is not present, the immutable can 57 57 be initialized from the corresponding constructor: 58 58 ) 59 59 60 60 --- 61 i nvariantint z;61 immutable int z; 62 62 void test() 63 63 { 64 z = 3; // error, z is i nvariant64 z = 3; // error, z is immutable 65 65 } 66 66 static this() 67 67 { 68 z = 3; // ok, can set i nvariantthat doesn't have68 z = 3; // ok, can set immutable that doesn't have 69 69 // static initializer 70 70 } 71 71 --- 72 72 $(P 73 The initializer for a non-local i nvariantdeclaration must be73 The initializer for a non-local immutable declaration must be 74 74 evaluatable 75 75 at compile time: … … 79 79 int foo(int f) { return f * 3; } 80 80 int i = 5; 81 i nvariantx = 3 * 4; // ok, 1282 i nvarianty = i + 1; // error, cannot evaluate at compile time83 i nvariantz = foo(2) + 1; // ok, foo(2) can be evaluated at compile time, 784 --- 85 86 $(P The initializer for a non-static local i nvariantdeclaration81 immutable x = 3 * 4; // ok, 12 82 immutable y = i + 1; // error, cannot evaluate at compile time 83 immutable z = foo(2) + 1; // ok, foo(2) can be evaluated at compile time, 7 84 --- 85 86 $(P The initializer for a non-static local immutable declaration 87 87 is evaluated at run time: 88 88 ) … … 90 90 int foo(int f) 91 91 { 92 i nvariantx = f + 1; // evaluated at run time93 x = 3; // error, x is i nvariant94 } 95 --- 96 97 $(P 98 Because i nvariant is transitive, data referred to by an invariantis99 also i nvariant:100 ) 101 102 --- 103 i nvariantchar[] s = "foo";104 s[0] = 'a'; // error, s refers to i nvariantdata105 s = "bar"; // error, s is i nvariant106 --- 107 108 $(P I nvariantdeclarations can appear as lvalues, i.e. they can92 immutable x = f + 1; // evaluated at run time 93 x = 3; // error, x is immutable 94 } 95 --- 96 97 $(P 98 Because immutable is transitive, data referred to by an immutable is 99 also immutable: 100 ) 101 102 --- 103 immutable char[] s = "foo"; 104 s[0] = 'a'; // error, s refers to immutable data 105 s = "bar"; // error, s is immutable 106 --- 107 108 $(P Immutable declarations can appear as lvalues, i.e. they can 109 109 have their address taken, and occupy storage. 110 110 ) … … 114 114 115 115 $(P 116 A const declaration is exactly like an i nvariantdeclaration,116 A const declaration is exactly like an immutable declaration, 117 117 with the following differences: 118 118 ) … … 180 180 $(TABLE1 181 181 <caption>Template Argument Deduced Type</caption> 182 $(TR $(TH ) $(TH mutable $(CODE T)) $(TH1 const(T)) $(TH1 i nvariant(T)))182 $(TR $(TH ) $(TH mutable $(CODE T)) $(TH1 const(T)) $(TH1 immutable(T))) 183 183 $(TR $(TD1 foo(U)) $(TDE T) $(TDE T) $(TDE T)) 184 $(TR $(TD1 foo(U:U)) $(TDE T) $(TDE const(T)) $(TDE i nvariant(T)))184 $(TR $(TD1 foo(U:U)) $(TDE T) $(TDE const(T)) $(TDE immutable(T))) 185 185 $(TR $(TD1 foo(U:const(U))) $(TDI T) $(TDE T) $(TDI T)) 186 $(TR $(TD1 foo(U:i nvariant(U))) $(NM) $(NM) $(TDE T))186 $(TR $(TD1 foo(U:immutable(U))) $(NM) $(NM) $(TDE T)) 187 187 ) 188 188 … … 196 196 ) 197 197 198 $(SECTION2 I nvariantType,199 200 $(P 201 Data that will never change its value can be typed as i nvariant.202 The i nvariantkeyword can be used as a $(I type constructor):203 ) 204 205 --- 206 i nvariant(char)[] s = "hello";207 --- 208 209 $(P 210 The i nvariantapplies to the type within the following parentheses.198 $(SECTION2 Immutable Type, 199 200 $(P 201 Data that will never change its value can be typed as immutable. 202 The immutable keyword can be used as a $(I type constructor): 203 ) 204 205 --- 206 immutable(char)[] s = "hello"; 207 --- 208 209 $(P 210 The immutable applies to the type within the following parentheses. 211 211 So, while $(CODE s) can be assigned new values, 212 212 the contents of $(CODE s[]) cannot be: … … 214 214 215 215 --- 216 s[0] = 'b'; // error, s[] is i nvariant217 s = null; // ok, s itself is not i nvariant218 --- 219 220 $(P 221 I nvariantness is transitive, meaning it applies to anything that222 can be referenced from the i nvarianttype:223 ) 224 225 --- 226 i nvariant(char*)** p = ...;227 p = ...; // ok, p is not i nvariant228 *p = ...; // ok, *p is not i nvariant229 **p = ...; // error, **p is i nvariant230 ***p = ...; // error, ***p is i nvariant231 --- 232 233 $(P I nvariantused as a storage class is equivalent to using234 i nvariantas a type constructor for the entire type of a216 s[0] = 'b'; // error, s[] is immutable 217 s = null; // ok, s itself is not immutable 218 --- 219 220 $(P 221 Immutableness is transitive, meaning it applies to anything that 222 can be referenced from the immutable type: 223 ) 224 225 --- 226 immutable(char*)** p = ...; 227 p = ...; // ok, p is not immutable 228 *p = ...; // ok, *p is not immutable 229 **p = ...; // error, **p is immutable 230 ***p = ...; // error, ***p is immutable 231 --- 232 233 $(P Immutable used as a storage class is equivalent to using 234 immutable as a type constructor for the entire type of a 235 235 declaration:) 236 236 237 237 --- 238 i nvariant int x = 3; // x is typed as invariant(int)239 i nvariant(int) y = 3; // y is invariant240 --- 241 ) 242 243 244 $(SECTION2 Creating I nvariantData,245 246 $(P 247 The first way is to use a literal that is already i nvariant,248 such as string literals. String literals are always i nvariant.249 ) 250 251 --- 252 auto s = "hello"; // s is i nvariant(char)[5]253 char[] p = "world"; // error, cannot implicitly convert i nvariant238 immutable int x = 3; // x is typed as immutable(int) 239 immutable(int) y = 3; // y is immutable 240 --- 241 ) 242 243 244 $(SECTION2 Creating Immutable Data, 245 246 $(P 247 The first way is to use a literal that is already immutable, 248 such as string literals. String literals are always immutable. 249 ) 250 251 --- 252 auto s = "hello"; // s is immutable(char)[5] 253 char[] p = "world"; // error, cannot implicitly convert immutable 254 254 // to mutable 255 255 --- 256 256 257 257 $(P 258 The second way is to cast data to i nvariant.258 The second way is to cast data to immutable. 259 259 When doing so, it is up to the programmer to ensure that no 260 260 other mutable references to the same data exist. … … 263 263 --- 264 264 char[] s = ...; 265 i nvariant(char)[] p = cast(invariant)s; // undefined behavior266 i nvariant(char)[] p = cast(invariant)s.dup; // ok, unique reference267 --- 268 269 $(P 270 The $(CODE .idup) property is a convenient way to create an i nvariant265 immutable(char)[] p = cast(immutable)s; // undefined behavior 266 immutable(char)[] p = cast(immutable)s.dup; // ok, unique reference 267 --- 268 269 $(P 270 The $(CODE .idup) property is a convenient way to create an immutable 271 271 copy of an array: 272 272 ) … … 274 274 --- 275 275 auto p = s.idup; 276 p[0] = ...; // error, p[] is i nvariant277 --- 278 279 <h2>Removing I nvariantWith A Cast</h2>280 281 $(P 282 The i nvarianttype can be removed with a cast:283 ) 284 285 --- 286 i nvariantint* p = ...;276 p[0] = ...; // error, p[] is immutable 277 --- 278 279 <h2>Removing Immutable With A Cast</h2> 280 281 $(P 282 The immutable type can be removed with a cast: 283 ) 284 285 --- 286 immutable int* p = ...; 287 287 int* q = cast(int*)p; 288 288 --- … … 297 297 298 298 $(P 299 The ability to cast away i nvariant-correctness is necessary in299 The ability to cast away immutable-correctness is necessary in 300 300 some cases where the static typing is incorrect and not fixable, such 301 301 as when referencing code in a library one cannot change. 302 302 Casting is, as always, a blunt and effective instrument, and 303 when using it to cast away i nvariant-correctness, one must assume304 the responsibility to ensure the i nvariantness of the data, as303 when using it to cast away immutable-correctness, one must assume 304 the responsibility to ensure the immutableness of the data, as 305 305 the compiler will no longer be able to statically do so. 306 306 ) … … 308 308 309 309 310 $(SECTION2 I nvariantMember Functions,311 312 $(P 313 I nvariantmember functions are guaranteed that the object314 and anything referred to by the $(CODE this) reference is i nvariant.310 $(SECTION2 Immutable Member Functions, 311 312 $(P 313 Immutable member functions are guaranteed that the object 314 and anything referred to by the $(CODE this) reference is immutable. 315 315 They are declared as: 316 316 ) … … 320 320 { int x; 321 321 322 i nvariantvoid foo()322 immutable void foo() 323 323 { 324 x = 4; // error, x is i nvariant325 this.x = 4; // error, x is i nvariant324 x = 4; // error, x is immutable 325 this.x = 4; // error, x is immutable 326 326 } 327 327 --- 328 328 329 $(P The $(D_KEYWORD const) and $(D_KEYWORD i nvariant) function329 $(P The $(D_KEYWORD const) and $(D_KEYWORD immutable) function 330 330 attributes 331 331 can also appear after the closing parenthesis of … … 336 336 struct S 337 337 { 338 void bar() i nvariant338 void bar() immutable 339 339 { 340 340 } … … 347 347 348 348 $(P 349 Const types are like i nvarianttypes, except that const349 Const types are like immutable types, except that const 350 350 forms a read-only $(I view) of data. Other aliases to that 351 351 same data may change it at any time. … … 367 367 368 368 $(P 369 Mutable and i nvarianttypes can be implicitly converted to const.370 Mutable types cannot be implicitly converted to i nvariant,369 Mutable and immutable types can be implicitly converted to const. 370 Mutable types cannot be implicitly converted to immutable, 371 371 and vice versa. 372 372 ) … … 374 374 375 375 376 $(SECTION2 Comparing D I nvariantand Const with C++ Const,376 $(SECTION2 Comparing D Immutable and Const with C++ Const, 377 377 378 378 <table border=2 cellpadding=4 cellspacing=0 class="comp"> 379 <caption>Const, I nvariantComparison</caption>379 <caption>Const, Immutable Comparison</caption> 380 380 381 381 <thead> … … 396 396 397 397 $(TR 398 $(TD i nvariantkeyword)398 $(TD immutable keyword) 399 399 $(TD Yes) 400 400 $(TD No) … … 520 520 521 521 $(TR 522 $(TD aliasing of i nvariantwith mutable)522 $(TD aliasing of immutable with mutable) 523 523 $(TD No: 524 524 --- 525 void foo(i nvariantint* x, int* y)525 void foo(immutable int* x, int* y) 526 526 { 527 527 bar(*x); // bar(3) … … 531 531 ... 532 532 int i = 3; 533 foo(cast(i nvariant)&i, &i);534 --- 535 ) 536 $(TD No i nvariants)533 foo(cast(immutable)&i, &i); 534 --- 535 ) 536 $(TD No immutables) 537 537 ) 538 538 539 539 $(TR 540 540 $(TD type of string literal) 541 $(TD i nvariant(char)[])541 $(TD immutable(char)[]) 542 542 $(TD const char*) 543 543 ) … … 565 565 Y=$(TD $(GREEN Yes)) 566 566 N=$(TD $(RED No)) 567 TITLE=Const and I nvariant567 TITLE=Const and Immutable 568 568 WIKI=ConstInvariant 569 569 NO=<td class="compNo">No</td> … … 575 575 ERROR = $(RED $(B error)) 576 576 COMMA=, 577 META_KEYWORDS=D Programming Language, const, i nvariant577 META_KEYWORDS=D Programming Language, const, immutable 578 578 META_DESCRIPTION=Comparison of const between the 579 579 D programming language, C++, and C++0x
