1
+ // RUN: %target-run-simple-swift(-parse-as-library -Xfrontend -enable-experimental-concurrency %import-libdispatch) | %FileCheck %s
2
+
3
+ // REQUIRES: executable_test
4
+ // REQUIRES: concurrency
5
+ // REQUIRES: libdispatch
6
+
7
+ enum GeneralError : Error {
8
+ case UnknownBallKind
9
+ case Todo
10
+ }
11
+
12
+ enum BallKind {
13
+ case MostLostV1
14
+ case Chromehard
15
+ case PT5
16
+ case KirksandLignature
17
+ }
18
+
19
+ class Specs {
20
+ // obtains the number of dimples
21
+ subscript( _ bk : BallKind ) -> Int {
22
+ get throws {
23
+ switch ( bk) {
24
+ case . MostLostV1:
25
+ return 450
26
+ case . Chromehard:
27
+ return 125
28
+ default :
29
+ throw GeneralError . UnknownBallKind
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ actor Database {
36
+ var currentData : Specs {
37
+ get async {
38
+ let handle = Task . runDetached { Specs ( ) }
39
+ print ( " obtaining specs... " )
40
+ return await handle. get ( )
41
+ }
42
+ }
43
+
44
+ var hasNewData : Bool {
45
+ get throws { return true }
46
+ }
47
+ }
48
+
49
+ protocol SphericalObject {
50
+ var name : String { get async throws }
51
+ var dimples : Int { get async throws }
52
+ var description : String { get async throws }
53
+ }
54
+
55
+ class Ball : SphericalObject {
56
+ var name : String { get async throws { throw GeneralError . Todo } }
57
+ var dimples : Int { get async throws { throw GeneralError . Todo } }
58
+ var description : String { get async throws { throw GeneralError . Todo } }
59
+ }
60
+
61
+ class GolfBall : Ball {
62
+ private static let db : Database = Database ( )
63
+
64
+ private var _model : BallKind
65
+ private var _dimples : Int ?
66
+
67
+ init ( _ bk : BallKind ) {
68
+ _model = bk
69
+ }
70
+
71
+ override var name : String {
72
+ return " golf ball "
73
+ }
74
+
75
+ override var description : String {
76
+ get async throws {
77
+ return " this \( name) has \( await dimples) dimples "
78
+ }
79
+ }
80
+
81
+ override var dimples : Int {
82
+ get async {
83
+ let newData = ( try ? await GolfBall . db. hasNewData) ?? false
84
+
85
+ if newData || _dimples == nil {
86
+ let specs = await GolfBall . db. currentData
87
+ _dimples = ( try ? specs [ _model] ) ?? 0
88
+ }
89
+
90
+ return _dimples!
91
+ }
92
+ }
93
+ }
94
+
95
+ // CHECK: obtaining specs...
96
+ // CHECK: this golf ball has 450 dimples
97
+ // CHECK: obtaining specs...
98
+ // CHECK: this golf ball has 125 dimples
99
+ // CHECK: obtaining specs...
100
+ // CHECK: this golf ball has 0 dimples
101
+ // CHECK: obtaining specs...
102
+ // CHECK: this golf ball has 0 dimples
103
+
104
+ func printAsBall( _ b : Ball ) async {
105
+ print ( try ! await b. description)
106
+ }
107
+
108
+ func printAsAsSphericalObject( _ b : SphericalObject ) async {
109
+ print ( try ! await b. description)
110
+ }
111
+
112
+ @main struct RunIt {
113
+ static func main( ) async {
114
+ let balls : [ ( Bool , Ball ) ] = [
115
+ ( true , GolfBall ( . MostLostV1) ) ,
116
+ ( false , GolfBall ( . Chromehard) ) ,
117
+ ( true , GolfBall ( . PT5) ) ,
118
+ ( false , GolfBall ( . KirksandLignature) )
119
+ ]
120
+ for (useProtocol, ball) in balls {
121
+ if ( useProtocol) {
122
+ await printAsAsSphericalObject ( ball)
123
+ } else {
124
+ await printAsBall ( ball)
125
+ }
126
+ }
127
+ }
128
+ }
0 commit comments