[swift-evolution] [Review] SE-0018 Flexible Memberwise Initialization
Kevin Ballard
kevin at sb.org
Thu Jan 7 15:37:16 CST 2016
On Thu, Jan 7, 2016, at 01:31 PM, Kevin Ballard wrote:
> On Thu, Jan 7, 2016, at 07:12 AM, Matthew Johnson wrote:
>>> As for my concern, it's with the following rule:
>>>
>>>> If the initializer body assigns to a var property that received
>>>> memberwise initialization synthesis report a warning. It is
>>>> unlikely that overwriting the value provided by the caller is the
>>>> desired behavior.
>>>
>>> I understand why you put this in there, but this is a warning that
>>> cannot be suppressed and will make it impossible to use a memberwise
>>> initializer for perfectly legitimate cases where you do in fact want
>>> to mutate the property after it's been assigned to.
>>
>> For normal initializers I agree with you. However, I think it’s a
>> reasonable for callers to assume that if you expose a property via
>> memberwise initialization the post-initialization value will match
>> the value they provide. This warning is intended to alert you to the
>> fact that you are violating that reasonable assumption.
>
> I think that's a reasonable assumption in many cases, but I don't like
> the fact that the feature cannot be used at all in the rare case where
> it actually makes sense to mutate the value.
>
>> Do you have an example of where you would want a caller to initialize
>> a property, but then overwrite the value they provide *during
>> initialization*?
>
> Sure, how about something like a Rect type that always guarantees it's
> in "standard" form (e.g. no negative sizes):
>
> struct StandardRect { var origin: CGPoint var size: CGSize {
> didSet { // ensure standardized form here } }
>
> memberwise init(...) { if size.width < 0 { origin.x
> += size.width size.width = -size.width } if
> size.height < 0 { origin.y += size.height
> size.height = -size.height } } }
>
> Or how about a struct that represents a URL request complete with
> headers, and forces the inclusion of Content-Type:
>
> struct URLRequest { var headers: [String: String] = [:] // ...
> other properties here ... memberwise init(contentType: String, ...)
> { headers["Content-Type"] = contentType } }
Here's an even better example, since it matches some code I actually
already have in a production app. Assuming that the "..." placeholder
can go anywhere (which seems reasonable), I have extensions on CGRect
and friends that could use memberwise init instead to be written like
extension CGRect { memberwise init(..., roundedToScale: CGFloat) }
This method takes the components of a rect, as well as a scale, and it
properly rounds the components so that the rect falls along pixel
boundaries if displayed on a screen with the given scale.
-Kevin Ballard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160107/8a400362/attachment.html>
More information about the swift-evolution
mailing list