Source file
src/sync/oncefunc.go
1
2
3
4
5 package sync
6
7
8
9
10
11 func OnceFunc(f func()) func() {
12
13 d := struct {
14 f func()
15 once Once
16 valid bool
17 p any
18 }{
19 f: f,
20 }
21 return func() {
22 d.once.Do(func() {
23 defer func() {
24 d.f = nil
25 d.p = recover()
26 if !d.valid {
27
28
29
30 panic(d.p)
31 }
32 }()
33 d.f()
34 d.valid = true
35 })
36 if !d.valid {
37 panic(d.p)
38 }
39 }
40 }
41
42
43
44
45
46 func OnceValue[T any](f func() T) func() T {
47
48 d := struct {
49 f func() T
50 once Once
51 valid bool
52 p any
53 result T
54 }{
55 f: f,
56 }
57 return func() T {
58 d.once.Do(func() {
59 defer func() {
60 d.f = nil
61 d.p = recover()
62 if !d.valid {
63 panic(d.p)
64 }
65 }()
66 d.result = d.f()
67 d.valid = true
68 })
69 if !d.valid {
70 panic(d.p)
71 }
72 return d.result
73 }
74 }
75
76
77
78
79
80 func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) {
81
82 d := struct {
83 f func() (T1, T2)
84 once Once
85 valid bool
86 p any
87 r1 T1
88 r2 T2
89 }{
90 f: f,
91 }
92 return func() (T1, T2) {
93 d.once.Do(func() {
94 defer func() {
95 d.f = nil
96 d.p = recover()
97 if !d.valid {
98 panic(d.p)
99 }
100 }()
101 d.r1, d.r2 = d.f()
102 d.valid = true
103 })
104 if !d.valid {
105 panic(d.p)
106 }
107 return d.r1, d.r2
108 }
109 }
110
View as plain text