Skip to content

Commit 54b2b2f

Browse files
authored
Add example of constant with deferred assignment (#172)
Fixes: #139 Fixes: rdar://114058607
2 parents 0a29526 + 0a57490 commit 54b2b2f

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

Style.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ Spelled as two words, not closed up or hyphenated.
111111

112112
See entry for *Swift*.
113113

114+
## definite initialization
115+
116+
Not “definitive initialization”.
117+
Don‘t abbreviate as DI.
118+
114119
## function
115120

116121
In the reference,

TSPL.docc/LanguageGuide/TheBasics.md

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,60 @@ because the maximum value never changes.
8282
The current login attempt counter is declared as a variable,
8383
because this value must be incremented after each failed login attempt.
8484

85+
If a stored value in your code won't change,
86+
always declare it as a constant with the `let` keyword.
87+
Use variables only for storing values that change.
88+
89+
When you declare a constant or a variable,
90+
you can give it a value as part of that declaration,
91+
like the examples above.
92+
Alternatively,
93+
you can assign its initial value later in the program,
94+
as long as it's guaranteed to have a value
95+
before the first time you read from it.
96+
97+
```swift
98+
var environment = "development"
99+
let maximumNumberOfLoginAttempts: Int
100+
// maximumNumberOfLoginAttempts has no value yet.
101+
102+
if environment == "development" {
103+
maximumNumberOfLoginAttempts = 100
104+
} else {
105+
maximumNumberOfLoginAttempts = 10
106+
}
107+
// Now maximumNumberOfLoginAttempts has a value, and can be read.
108+
```
109+
110+
<!--
111+
- test: `constantsWithDeferredInitialization`
112+
113+
```swifttest
114+
-> var environment = "development"
115+
-> let maximumNumberOfLoginAttempts: Int
116+
-> if environment == "development" {
117+
maximumNumberOfLoginAttempts = 100
118+
} else {
119+
maximumNumberOfLoginAttempts = 10
120+
}
121+
>> print(maxNumberOfLoginAttempts)
122+
<< 100
123+
```
124+
-->
125+
126+
In this example,
127+
the maximum number of login attempts is constant,
128+
and its value depends on the environment.
129+
In the development environment,
130+
it has a value of 100;
131+
in any other environment, its value is 10.
132+
Both branches of the `if` statement
133+
initialize `maximumNumberOfLoginAttempts` with some value,
134+
guaranteeing that the constant always gets a value.
135+
For information about how Swift checks your code
136+
when you set an initial value this way,
137+
see <doc:Declarations#Constant-Declaration>.
138+
85139
You can declare multiple constants or multiple variables on a single line,
86140
separated by commas:
87141

@@ -99,10 +153,6 @@ var x = 0.0, y = 0.0, z = 0.0
99153
```
100154
-->
101155

102-
> Note: If a stored value in your code won't change,
103-
> always declare it as a constant with the `let` keyword.
104-
> Use variables only for storing values that need to be able to change.
105-
106156
### Type Annotations
107157

108158
You can provide a *type annotation* when you declare a constant or variable,

TSPL.docc/ReferenceManual/Declarations.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,24 @@ as long as it's guaranteed to have a value set
156156
before the first time its value is read.
157157
If the compiler can prove that the constant's value is never read,
158158
the constant isn't required to have a value set at all.
159+
This analysis is called *definite initialization* ---
160+
the compiler proves that a value is definitely set before being read.
161+
162+
> Note:
163+
> Definite initialization
164+
> can't construct proofs that require domain knowledge,
165+
> and its ability to track state across conditionals has a limit.
166+
> If you can determine that constant always has a value set,
167+
> but the compiler can't prove this is the case,
168+
> try simplifying the code paths that set the value,
169+
> or use a variable declaration instead.
170+
171+
<!--
172+
In the most general case,
173+
DI reduces to the halting problem,
174+
as shown by Rice's theorem.
175+
-->
176+
159177
When a constant declaration occurs in the context of a class or structure
160178
declaration, it's considered a *constant property*.
161179
Constant declarations aren't computed properties and therefore don't have getters
@@ -277,6 +295,9 @@ That said, if no initializer *expression* is present,
277295
the variable declaration must include an explicit type annotation (`:` *type*).
278296

279297
As with constant declarations,
298+
if a variable declaration omits the initializer *expression*,
299+
the variable must have a value set before the first time it is read.
300+
Also like constant declarations,
280301
if the *variable name* is a tuple pattern,
281302
the name of each item in the tuple is bound to the corresponding value
282303
in the initializer *expression*.

0 commit comments

Comments
 (0)