Skip to content

Commit 20ae92c

Browse files
authored
Merge pull request #12 from RougeWare/feature/9-Examples-In-Readme
#9 Added examples to readme
2 parents b627819 + fc2cff7 commit 20ae92c

File tree

2 files changed

+243
-4
lines changed

2 files changed

+243
-4
lines changed

README.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,186 @@ A few ways to have a lazily-initialized value in Swift 5.1. Note that, if you ar
1414
The entire repository structure had to be changed in order to be compatible with Swift Package Manager ([#4](https://github.com/RougeWare/Swift-Lazy-Patterns/issues/4)). Because of this, the API version changed from 2.0.0 to 3.0.0. Very little of the actual API changed along with this ([#8](https://github.com/RougeWare/Swift-Lazy-Patterns/issues/8)); it was almost entirely to service Swift Package manager.
1515

1616
In version 2.0.0, [this readme recommended](https://github.com/RougeWare/Swift-Lazy-Patterns/commit/68fd42023fe5642dd9841ea1411027f6cbc1032f#diff-04c6e90faac2675aa89e2176d2eec7d8) that you change any reference to `./Lazy.swift` to `./LazyContainers/Sources/LazyContainers/LazyContainers.swift`. Unfortunately, that wasn't compatible with Swift Package Manager, so `./Lazy.swift` was changed to `./Sources/LazyContainers/LazyContainers.swift`. Because of this, please change any reference to `./LazyContainers/Sources/LazyContainers/LazyContainers.swift` to `./Sources/LazyContainers/LazyContainers.swift`. Sorry about that 🤷🏽‍
17+
18+
19+
20+
# Examples #
21+
22+
It's easy to use each of these. Simply place the appropriate one as a property wrapper where you want it.
23+
24+
25+
## `Lazy` ##
26+
27+
The simple usage of this is very straightforward:
28+
29+
```swift
30+
31+
@Lazy
32+
var myLazyString = "Hello, lazy!"
33+
34+
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
35+
print(myLazyString) // Just returns the value "Hello, lazy!"
36+
37+
myLazyString = "Overwritten"
38+
print(myLazyString) // Just returns the value "Overwritten"
39+
print(myLazyString) // Just returns the value "Overwritten"
40+
```
41+
42+
This will print:
43+
44+
```plain
45+
Hello, lazy!
46+
Hello, lazy!
47+
Overwritten
48+
Overwritten
49+
```
50+
51+
### More complex initializer ##
52+
53+
If you have complex initializer logic, you can pass that to the property wrapper:
54+
55+
```swift
56+
57+
func makeLazyString() -> String {
58+
print("Initializer side-effect")
59+
return "Hello, lazy!"
60+
}
61+
62+
@Lazy(initializer: makeLazyString)
63+
var myLazyString: String
64+
65+
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
66+
print(myLazyString) // Just returns the value "Hello, lazy!"
67+
68+
myLazyString = "Overwritten"
69+
print(myLazyString) // Just returns the value "Overwritten"
70+
print(myLazyString) // Just returns the value "Overwritten"
71+
```
72+
73+
You can also use it directly (instaed of as a property wrapper):
74+
75+
```swift
76+
var myLazyString = Lazy<String>() {
77+
print("Initializer side-effect")
78+
return "Hello, lazy!"
79+
}
80+
81+
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
82+
print(myLazyString.wrappedValue) // Just returns the value "Hello, lazy!"
83+
84+
myLazyString.wrappedValue = "Overwritten"
85+
print(myLazyString.wrappedValue) // Just returns the value "Overwritten"
86+
print(myLazyString.wrappedValue) // Just returns the value "Overwritten"
87+
```
88+
89+
These will both print:
90+
91+
```plain
92+
Initializer side-effect
93+
Hello, lazy!
94+
Hello, lazy!
95+
Overwritten
96+
Overwritten
97+
```
98+
99+
100+
## `ResettableLazy` ##
101+
102+
The simple usage of this is very straightforward:
103+
104+
```swift
105+
106+
@ResettableLazy
107+
var myLazyString = "Hello, lazy!"
108+
109+
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
110+
print(myLazyString) // Just returns the value "Hello, lazy!"
111+
112+
_myLazyString.clear()
113+
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
114+
print(myLazyString) // Just returns the value "Hello, lazy!"
115+
116+
myLazyString = "Overwritten"
117+
print(myLazyString) // Just returns the value "Overwritten"
118+
_myLazyString.clear()
119+
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
120+
```
121+
122+
This will print:
123+
124+
```plain
125+
Hello, lazy!
126+
Hello, lazy!
127+
Hello, lazy!
128+
Hello, lazy!
129+
Overwritten
130+
Hello, lazy!
131+
```
132+
133+
### More complex initializer ##
134+
135+
If you have complex initializer logic, you can pass that to the property wrapper:
136+
137+
```swift
138+
139+
func makeLazyString() -> String {
140+
print("Initializer side-effect")
141+
return "Hello, lazy!"
142+
}
143+
144+
@ResettableLazy(initializer: makeLazyString)
145+
var myLazyString: String
146+
147+
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
148+
print(myLazyString) // Just returns the value "Hello, lazy!"
149+
150+
_myLazyString.clear()
151+
print(myLazyString) // Initializes, caches, and returns the value "Hello, lazy!"
152+
print(myLazyString) // Just returns the value "Hello, lazy!"
153+
154+
myLazyString = "Overwritten"
155+
print(myLazyString) // Just returns the value "Overwritten"
156+
_myLazyString.clear()
157+
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
158+
```
159+
160+
You can also use it directly (instaed of as a property wrapper):
161+
162+
```swift
163+
var myLazyString = ResettableLazy<String>() {
164+
print("Initializer side-effect")
165+
return "Hello, lazy!"
166+
}
167+
168+
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
169+
print(myLazyString.wrappedValue) // Just returns the value "Hello, lazy!"
170+
171+
myLazyString.clear()
172+
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
173+
print(myLazyString.wrappedValue) // Just returns the value "Hello, lazy!"
174+
175+
myLazyString.wrappedValue = "Overwritten"
176+
print(myLazyString.wrappedValue) // Just returns the value "Overwritten"
177+
_myLazyString.clear()
178+
print(myLazyString.wrappedValue) // Initializes, caches, and returns the value "Hello, lazy!"
179+
```
180+
181+
These will both print:
182+
183+
```plain
184+
Initializer side-effect
185+
Hello, lazy!
186+
Hello, lazy!
187+
Initializer side-effect
188+
Hello, lazy!
189+
Hello, lazy!
190+
Overwritten
191+
Initializer side-effect
192+
Hello, lazy!
193+
```
194+
195+
196+
197+
## `FunctionalLazy` ##
198+
199+
This is functionally <sub>(ha!)</sub> the same as `Lazy`. The only difference is I thought it'd be fun to implement it with functions instead of enums. 🤓

Tests/LazyContainersTests/LazyContainersTests.swift

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,24 @@ import XCTest
1212

1313

1414

15+
var sideEffect: String?
16+
17+
func makeLazyA() -> String {
18+
sideEffect = "Side effect A"
19+
return "lAzy"
20+
}
21+
22+
23+
1524
final class LazyContainersTests: XCTestCase {
1625

17-
@Lazy
18-
var lazyInitWithPropertyWrapper = "lAzy"
26+
@Lazy(initializer: makeLazyA)
27+
var lazyInitWithPropertyWrapper: String
1928

20-
var lazyInitTraditionally = Lazy(wrappedValue: "lazy B")
29+
var lazyInitTraditionally = Lazy<String>() {
30+
sideEffect = "Side effect B"
31+
return "lazy B"
32+
}
2133

2234
@ResettableLazy
2335
var resettableLazyInitWithPropertyWrapper = "lazy C"
@@ -31,7 +43,7 @@ final class LazyContainersTests: XCTestCase {
3143

3244

3345
override func setUp() {
34-
// Put setup code here. This method is called before the invocation of each test method in the class.
46+
sideEffect = nil
3547
}
3648

3749

@@ -44,23 +56,39 @@ final class LazyContainersTests: XCTestCase {
4456
// MARK: - `Lazy`
4557

4658
func testLazyInitWithPropertyWrapper() {
59+
XCTAssertEqual(sideEffect, nil)
4760
XCTAssertFalse(_lazyInitWithPropertyWrapper.isInitialized)
61+
XCTAssertEqual(sideEffect, nil)
4862
XCTAssertEqual("lAzy", lazyInitWithPropertyWrapper)
63+
XCTAssertEqual(sideEffect, "Side effect A")
4964
XCTAssertTrue(_lazyInitWithPropertyWrapper.isInitialized)
65+
XCTAssertEqual(sideEffect, "Side effect A")
5066
XCTAssertEqual("lAzy", lazyInitWithPropertyWrapper)
67+
XCTAssertEqual(sideEffect, "Side effect A")
5168
XCTAssertTrue(_lazyInitWithPropertyWrapper.isInitialized)
69+
XCTAssertEqual(sideEffect, "Side effect A")
5270
XCTAssertEqual("lAzy", lazyInitWithPropertyWrapper)
71+
XCTAssertEqual(sideEffect, "Side effect A")
5372
XCTAssertTrue(_lazyInitWithPropertyWrapper.isInitialized)
73+
XCTAssertEqual(sideEffect, "Side effect A")
5474

5575
lazyInitWithPropertyWrapper = "MAnual"
5676

77+
XCTAssertEqual(sideEffect, "Side effect A")
5778
XCTAssertTrue(_lazyInitWithPropertyWrapper.isInitialized)
79+
XCTAssertEqual(sideEffect, "Side effect A")
5880
XCTAssertEqual("MAnual", lazyInitWithPropertyWrapper)
81+
XCTAssertEqual(sideEffect, "Side effect A")
5982
XCTAssertTrue(_lazyInitWithPropertyWrapper.isInitialized)
83+
XCTAssertEqual(sideEffect, "Side effect A")
6084
XCTAssertEqual("MAnual", lazyInitWithPropertyWrapper)
85+
XCTAssertEqual(sideEffect, "Side effect A")
6186
XCTAssertTrue(_lazyInitWithPropertyWrapper.isInitialized)
87+
XCTAssertEqual(sideEffect, "Side effect A")
6288
XCTAssertEqual("MAnual", lazyInitWithPropertyWrapper)
89+
XCTAssertEqual(sideEffect, "Side effect A")
6390
XCTAssertTrue(_lazyInitWithPropertyWrapper.isInitialized)
91+
XCTAssertEqual(sideEffect, "Side effect A")
6492
}
6593

6694

@@ -72,6 +100,12 @@ final class LazyContainersTests: XCTestCase {
72100
XCTAssertTrue(lazyInitTraditionally.isInitialized)
73101
XCTAssertEqual("lazy B", lazyInitTraditionally.wrappedValue)
74102
XCTAssertTrue(lazyInitTraditionally.isInitialized)
103+
XCTAssertEqual("lazy B", lazyInitTraditionally.value)
104+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
105+
XCTAssertEqual("lazy B", lazyInitTraditionally.value)
106+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
107+
XCTAssertEqual("lazy B", lazyInitTraditionally.value)
108+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
75109

76110
lazyInitTraditionally.wrappedValue = "Manual B"
77111

@@ -82,6 +116,28 @@ final class LazyContainersTests: XCTestCase {
82116
XCTAssertTrue(lazyInitTraditionally.isInitialized)
83117
XCTAssertEqual("Manual B", lazyInitTraditionally.wrappedValue)
84118
XCTAssertTrue(lazyInitTraditionally.isInitialized)
119+
XCTAssertEqual("Manual B", lazyInitTraditionally.value)
120+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
121+
XCTAssertEqual("Manual B", lazyInitTraditionally.value)
122+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
123+
XCTAssertEqual("Manual B", lazyInitTraditionally.value)
124+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
125+
126+
lazyInitTraditionally.value = "Manual B2"
127+
128+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
129+
XCTAssertEqual("Manual B2", lazyInitTraditionally.wrappedValue)
130+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
131+
XCTAssertEqual("Manual B2", lazyInitTraditionally.wrappedValue)
132+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
133+
XCTAssertEqual("Manual B2", lazyInitTraditionally.wrappedValue)
134+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
135+
XCTAssertEqual("Manual B2", lazyInitTraditionally.value)
136+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
137+
XCTAssertEqual("Manual B2", lazyInitTraditionally.value)
138+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
139+
XCTAssertEqual("Manual B2", lazyInitTraditionally.value)
140+
XCTAssertTrue(lazyInitTraditionally.isInitialized)
85141
}
86142

87143

0 commit comments

Comments
 (0)