You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -503,7 +503,7 @@ write out the getters and setters, and it's fairly common to have a `Box` type t
503
503
```swift
504
504
@propertyWrapper
505
505
classBox<Value> {
506
-
varvalue: Value
506
+
varwrappedValue: Value
507
507
508
508
init(initialValue: Value) {
509
509
self.value= initialValue
@@ -537,7 +537,7 @@ There are a number of existing types that already provide the basic structure of
537
537
structUnsafeMutablePointer<Pointee> {
538
538
var pointee: Pointee { ... }
539
539
540
-
varvalue: Pointee {
540
+
varwrappedValue: Pointee {
541
541
get { return pointee }
542
542
set { pointee = newValue }
543
543
}
@@ -556,7 +556,7 @@ print(someInt)
556
556
$someInt.deallocate()
557
557
```
558
558
559
-
RxCocoa's [`BehaviorRelay`](https://github.com/ReactiveX/RxSwift/blob/master/RxCocoa/Traits/BehaviorRelay.swift) replays the most recent value provided to it for each of the subscribed observers. It is created with an initial value, has `value` property to access the current value, as well as API to `subscribe` a new observer: (Thanks to Adrian Zubarev for pointing this out)
559
+
RxCocoa's [`BehaviorRelay`](https://github.com/ReactiveX/RxSwift/blob/master/RxCocoa/Traits/BehaviorRelay.swift) replays the most recent value provided to it for each of the subscribed observers. It is created with an initial value, has `wrappedValue` property to access the current value, as well as API to `subscribe` a new observer: (Thanks to Adrian Zubarev for pointing this out)
560
560
561
561
```swift
562
562
@BehaviorRelay
@@ -579,7 +579,7 @@ the wrappers are composed together to get both effects. For example, consider th
579
579
580
580
Here, we have a property for which we can delay initialization until later. When we do set a value, it will be copied via `NSCopying`'s `copy` method.
581
581
582
-
Composition is implemented by nesting later wrapper types inside earlier wrapper types, where the innermost nested type is the original property's type. For the example above, the backing storage will be of type `DelayedMutable<Copying<UIBezierPath>>`, and the synthesized getter/setter for `path` will look through both levels of `.value`:
582
+
Composition is implemented by nesting later wrapper types inside earlier wrapper types, where the innermost nested type is the original property's type. For the example above, the backing storage will be of type `DelayedMutable<Copying<UIBezierPath>>`, and the synthesized getter/setter for `path` will look through both levels of `.wrappedValue`:
583
583
584
584
```swift
585
585
var $path: DelayedMutable<Copying<UIBezierPath>>= .init()
@@ -610,7 +610,7 @@ type:
610
610
`@propertyWrapper`. The attribute indicates that the type is meant to
611
611
be used as a property wrapper type, and provides a point at which the
612
612
compiler can verify any other consistency rules.
613
-
2. The property wrapper type must have a property named `value`, whose
613
+
2. The property wrapper type must have a property named `wrappedValue`, whose
614
614
access level is the same as that of the type itself. This is the
615
615
property used by the compiler to access the underlying value on the
616
616
wrapper instance.
@@ -625,7 +625,7 @@ in one of three ways:
625
625
1. Via a value of the original property's type (e.g., `Int` in `@Lazy var
626
626
foo: Int`, using the the property wrapper type's
627
627
`init(initialValue:)` initializer. That initializer must have a single
628
-
parameter of the same type as the `value` property (or
628
+
parameter of the same type as the `wrappedValue` property (or
629
629
be an `@autoclosure` thereof) and have the same access level as the
630
630
property wrapper type itself. When `init(initialValue:)` is present,
631
631
is is always used for the initial value provided on the property
@@ -708,30 +708,30 @@ If the first property wrapper type is generic, its generic arguments must either
708
708
// infers the type of `$someInt` to be `UnsafeMutablePointer<Int>`
709
709
```
710
710
711
-
* Otherwise, if there is no initialization, and the original property has a type annotation, the type of the `value` property in the last wrapper type is constrained to equal the type annotation of the original property. For example:
711
+
* Otherwise, if there is no initialization, and the original property has a type annotation, the type of the `wrappedValue` property in the last wrapper type is constrained to equal the type annotation of the original property. For example:
In any case, the first wrapper type is constrained to be a specialization of the first attribute's written type. Furthermore, for any secondary wrapper attributes, the type of the value property of the previous wrapper type is constrained to be a specialization of the attribute's written type. Finally, if a type annotation is given, the type of the value property of the last wrapper type is constrained to equal the type annotation. If these rules fail to deduce all the type arguments for the first wrapper type, or if they are inconsistent with each other, the variable is ill-formed. For example:
722
+
In any case, the first wrapper type is constrained to be a specialization of the first attribute's written type. Furthermore, for any secondary wrapper attributes, the type of the wrappedValue property of the previous wrapper type is constrained to be a specialization of the attribute's written type. Finally, if a type annotation is given, the type of the wrappedValue property of the last wrapper type is constrained to equal the type annotation. If these rules fail to deduce all the type arguments for the first wrapper type, or if they are inconsistent with each other, the variable is ill-formed. For example:
723
723
724
724
```swift
725
725
@Lazy<Int>var foo: Int// okay
726
-
@Lazy<Int>var bar: Double// error: Lazy<Int>.value is of type Int, not Double
726
+
@Lazy<Int>var bar: Double// error: Lazy<Int>.wrappedValue is of type Int, not Double
727
727
```
728
728
729
729
The deduction can also provide a type for the original property (if a type annotation was omitted) or deduce generic arguments that have omitted from the type annotation. For example:
@@ -759,30 +759,30 @@ This formulation of custom attributes fits in with a [larger proposal for custom
759
759
760
760
### Mutability of properties with wrappers
761
761
762
-
Generally, a property that has a property wrapper will have both a getter and a setter. However, the setter may be missing if the `value` property of the property wrapper type lacks a setter, or its setter is inaccessible.
762
+
Generally, a property that has a property wrapper will have both a getter and a setter. However, the setter may be missing if the `wrappedValue` property of the property wrapper type lacks a setter, or its setter is inaccessible.
763
763
764
-
The synthesized getter will be `mutating` if the property wrapper type's `value` property is `mutating` and the property is part of a `struct`. Similarly, the synthesized setter will be `nonmutating` if either the property wrapper type's `value` property has a `nonmutating` setter or the property wrapper type is a `class`. For example:
764
+
The synthesized getter will be `mutating` if the property wrapper type's `wrappedValue` property is `mutating` and the property is part of a `struct`. Similarly, the synthesized setter will be `nonmutating` if either the property wrapper type's `wrappedValue` property has a `nonmutating` setter or the property wrapper type is a `class`. For example:
765
765
766
766
```swift
767
767
@propertyWrapper
768
768
structMutatingGetterWrapper<Value> {
769
-
varvalue: Value {
769
+
varwrappedValue: Value {
770
770
mutatingget { ... }
771
771
set { ... }
772
772
}
773
773
}
774
774
775
775
@propertyWrapper
776
776
structNonmutatingSetterWrapper<Value> {
777
-
varvalue: Value {
777
+
varwrappedValue: Value {
778
778
get { ... }
779
779
nonmutatingset { ... }
780
780
}
781
781
}
782
782
783
783
@propertyWrapper
784
784
classReferenceWrapper<Value> {
785
-
varvalue: Value
785
+
varwrappedValue: Value
786
786
}
787
787
788
788
structUsewrappers {
@@ -897,7 +897,7 @@ let $y = 17 // error: cannot declare entity with $-prefixed name '$y'
897
897
898
898
### Delegating access to the storage property
899
899
900
-
A property wrapper type can choose to hide its instance entirely by providing a property named `wrapperValue`. As with the `value` property and`init(initialValue:)`, the `wrapperValue` property must have the
900
+
A property wrapper type can choose to hide its instance entirely by providing a property named `wrapperValue`. As with the `wrappedValue` property and`init(initialValue:)`, the `wrapperValue` property must have the
901
901
same access level as its property wrapper type. When present, the synthesized storage property is hidden completely and the property `$foo` becomes a computed property accessing the storage property's `wrapperValue`. For example:
@@ -986,7 +986,7 @@ There are a number of restrictions on the use of property wrappers when defining
986
986
* A property with a wrapper cannot be `lazy`, `@NSCopying`, `@NSManaged`, `weak`, or `unowned`.
987
987
* A property with a wrapper must be the only property declared within its enclosing declaration (e.g., `@Lazy var (x, y) = /* ... */` is ill-formed).
988
988
* A property with a wrapper shall not define a getter or setter.
989
-
* The `value` property and (if present) `init(initialValue:)` of a property wrapper type shall have the same access as the property wrapper type.
989
+
* The `wrappedValue` property and (if present) `init(initialValue:)` of a property wrapper type shall have the same access as the property wrapper type.
990
990
* The `wrapperValue` property, if present, shall have the same access as the property wrapper type.
991
991
* The `init()` initializer, if present, shall have the same access as the property wrapper type.
992
992
@@ -1019,7 +1019,7 @@ Composition was left out of the [first revision](https://github.com/apple/swift-
1019
1019
structAB<Value> {
1020
1020
privatevar storage: A<B<Value>>
1021
1021
1022
-
varvalue: Value {
1022
+
varwrappedValue: Value {
1023
1023
get { storage.value.value }
1024
1024
set { storage.value.value= newValue }
1025
1025
}
@@ -1034,7 +1034,7 @@ One proposed approach to composition addresses only the last issue above directl
1034
1034
```swift
1035
1035
@propertyWrapper
1036
1036
structA<Value> {
1037
-
varvalue: Value { ... }
1037
+
varwrappedValue: Value { ... }
1038
1038
}
1039
1039
1040
1040
extensionA {
@@ -1054,7 +1054,7 @@ There has been a desire to effect composition of property wrappers without havin
1054
1054
@A@Bvar x: Int
1055
1055
```
1056
1056
1057
-
the `Int` value is conceptually wrapped by a property wrapper type, and the property wrapper type's `value` property guards access to that (conceptual) `Int` value. That `Int` value cannot be wrapped both by instances of both `A` and `B` without either duplicating data (both `A` and `B` have a copy of the `Int`) or nesting one of the wrappers inside the other. With the copying approach, one must maintain consistency between the copies (which is particularly hard when value types are involved) and there will still be non-commutative compositions. Nesting fits better with the "wrapper" model of property wrappers.
1057
+
the `Int` value is conceptually wrapped by a property wrapper type, and the property wrapper type's `wrappedValue` property guards access to that (conceptual) `Int` value. That `Int` value cannot be wrapped both by instances of both `A` and `B` without either duplicating data (both `A` and `B` have a copy of the `Int`) or nesting one of the wrappers inside the other. With the copying approach, one must maintain consistency between the copies (which is particularly hard when value types are involved) and there will still be non-commutative compositions. Nesting fits better with the "wrapper" model of property wrappers.
1058
1058
1059
1059
### Using a formal protocol instead of `@propertyWrapper`
1060
1060
@@ -1065,12 +1065,12 @@ types. It might look like this:
1065
1065
```swift
1066
1066
protocolPropertyWrapper {
1067
1067
associatedtypeValue
1068
-
varvalue: Value { get }
1068
+
varwrappedValue: Value { get }
1069
1069
}
1070
1070
```
1071
1071
1072
1072
There are a few issues here. First, a single protocol
1073
-
`PropertyWrapper` cannot handle all of the variants of `value` that
1073
+
`PropertyWrapper` cannot handle all of the variants of `wrappedValue` that
1074
1074
are implied by the section on mutability of properties with wrappers,
1075
1075
because we'd need to cope with `mutating get` as well as `set` and
1076
1076
`nonmutating set`. Moreover, protocols don't support optional
@@ -1152,7 +1152,7 @@ One could also consider having the property wrapper types themselves declare tha
1152
1152
```swift
1153
1153
@propertyWrapper(wrapperIsAccessible:true)
1154
1154
structAtomic<T> {
1155
-
varvalue: T { ... }
1155
+
varwrappedValue: T { ... }
1156
1156
}
1157
1157
1158
1158
// both bar and $bar are publicly visible
@@ -1201,7 +1201,7 @@ public struct Observable<Value> {
1201
1201
self.observed= observed
1202
1202
}
1203
1203
1204
-
publicvarvalue: Value {
1204
+
publicvarwrappedValue: Value {
1205
1205
get { return stored }
1206
1206
set {
1207
1207
if newValue != stored {
@@ -1229,7 +1229,7 @@ public class MyClass: Superclass {
1229
1229
1230
1230
This isn't as automatic as we would like, and it requires us to have a separate reference to the `self` that is stored within `Observable`.
1231
1231
1232
-
Instead, we could extend the ad hoc protocol used to access the storage property of a `@propertyWrapper` type a bit further. Instead of (or in addition to) a `value` property, a property wrapper type could provide a `subscript(instanceSelf:)` and/or `subscript(typeSelf:)` that receive `self` as a parameter. For example:
1232
+
Instead, we could extend the ad hoc protocol used to access the storage property of a `@propertyWrapper` type a bit further. Instead of (or in addition to) a `wrappedValue` property, a property wrapper type could provide a `subscript(instanceSelf:)` and/or `subscript(typeSelf:)` that receive `self` as a parameter. For example:
1233
1233
1234
1234
1235
1235
```swift
@@ -1272,7 +1272,7 @@ This change is backward-compatible with the rest of the proposal. Property wrapp
1272
1272
1273
1273
* For instance properties, `subscript(instanceSelf:)` as shown above.
1274
1274
* For static or class properties, `subscript(typeSelf:)`, similar to the above but accepting a metatype parameter.
1275
-
* For global/local properties, or when the appropriate `subscript` mentioned above isn't provided by the wrapper type, the `value` property would be used.
1275
+
* For global/local properties, or when the appropriate `subscript` mentioned above isn't provided by the wrapper type, the `wrappedValue` property would be used.
1276
1276
1277
1277
The main challenge with this design is that it doesn't directly work when the enclosing type is a value type and the property is settable. In such cases, the parameter to the subscript would get a copy of the entire enclosing value, which would not allow mutation, On the other hand, one could try to pass `self` as `inout`, e.g.,
1278
1278
@@ -1314,7 +1314,8 @@ One could express this either by naming the property directly (as above) or, for
1314
1314
* Reduced the visibility of the synthesized storage property to `private`, and expanded upon potential future directions to making it more visible.
1315
1315
* Removed the restriction banning property wrappers from having names that match the regular expression `_*[a-z].*`.
1316
1316
*`Codable`, `Hashable`, and `Equatable` synthesis are now based on the backing storage properties, which is a simpler model that gives more control to the authors of property wrapper types.
1317
-
* Improved type inference for property wrapper types and clarified that the type of the `value` property is used as part of this inference. See the "Type inference" section.
1317
+
* Improved type inference for property wrapper types and clarified that the type of the `wrappedValue` property is used as part of this inference. See the "Type inference" section.
1318
+
* Renamed the `value` property to `wrappedValue` to avoid conflicts.
0 commit comments