[swift-users] Capturing structs by reference

Zhao Xin owenzx at gmail.com
Sun Jul 24 07:49:26 CDT 2016


Below code works.

struct MyValueType {



    var x: () -> () {

        return { print(self) }

    }



    init() {

//        self.x = {

//            print(self)

//        }

    }

}


let a = MyValueType()

a.x() // MyValueType()

Zhaoxin

On Sun, Jul 24, 2016 at 5:11 PM, Tyler Fleming Cloutier via swift-users <
swift-users at swift.org> wrote:

> Also if capture lists for structs do capture by value, how can I avoid the
> newly added error “Closure cannot implicitly capture a mutating self
> parameter” without changing the original reference semantics of MyValueType?
>
> Also why can’t I specify weak self for value types in capture lists if a
> captured value type is really just a reference anyway? What’s the purpose
> of that?
>
>
> On Jul 24, 2016, at 2:07 AM, Tyler Fleming Cloutier <cloutiertyler at aol.com>
> wrote:
>
> The Swift Programming Language book states:
>
> "Reference counting only applies to instances of classes. Structures and
> enumerations are value types, not reference types, and are not stored and
> passed by reference.”
>
> However consider the following example.
>
> func makeIncrementer() -> (() -> Int, () -> Int) {
>     var runningTotal = 0
>
>     func incrementer() -> Int {
>         runningTotal += 1
>         return runningTotal
>     }
>
>     func incrementer2() -> Int {
>         runningTotal += 1
>         return runningTotal
>     }
>
>     return (incrementer, incrementer2)
> }
>
> let x = makeIncrementer()
>
> x.0() // 1
> x.1() // 2
>
> Clearly runningTotal is captured by reference by both incrementer and
> incrementer2. Is closure capturing the only case in which value types are
> treated as reference types?
>
> Why wouldn’t Swift be implement so that runningTotal was Captured as a
> static copy at the time of capture so that each of the incrementer
> functions has their own “value”?
>
> It seems like you could pretty easily run into a retain cycle with a
> struct even though it is a value type!
>
> Consider:
>
> struct MyValueType {
>
>     var x: () -> ()
>
>     init() {
>         self.x = {
>             print(self)
>         }
>     }
>
> }
>
> One might imagine that the capture of a value type like MyValueType would
> make a static copy of self for the closure, but if I understand correctly I
> actually just get a retain cycle. But it’s even worse, because (as I
> understand it) whether I do or not is optimization dependent!
>
> "As an optimization, Swift may instead capture and store a *copy* of a
> value if that value is not mutated by a closure, and if the value is not
> mutated after the closure is created.”
>
> Now it turns out that as of SE-0035 I get an error for the above code.
> Namely,
>
> “Closure cannot implicitly capture a mutating self parameter.”
>
> Kind of a strange error message for two reasons. The first is that nothing
> appears to be doing any mutating or declaring an intention of mutating. The
> second is that it’s not clear at all (to me at least) how to go about
> remedying the issue.
>
> If I capture self explicitly with something like [s = self], am I getting
> a copy of self or a reference to self? I would assume a copy of self, but
> that’s not super clear given the somewhat surprising behavior of capturing
> value types by reference.
>
> I would think the following would be a valid solution. Is there a better
> one?
>
> struct MyValueType {
>
>     var x: (() -> ())!
>
>     init() {
>         self.x = nil
>         self.x = { [s = self] in
>             print(s)
>         }
>     }
>
> }
>
> Is there a way to use currying to be more explicit about the semantics of
> passing a value into a closure?
>
> Any help or discussion would be much appreciated!
>
> Tyler
>
>
>
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160724/b4bbeb87/attachment.html>


More information about the swift-users mailing list