Dear Susan,
> Am 20.07.2016 um 14:14 schrieb Susan Cheng <[email protected]>:
>
> I forgot to reply, a shared value type can capture by multiple closures.
>
> func twoThreads() -> (Thread, Thread) {
> var shared_int = 0
> return (Thread { shared_int = 1 }, Thread { shared_int = 2 })
> }
You are not sharing the value type, but the reference to it (so you share the
surrounding function context *by reference* or more precisely via *call by
sharing*). I use an array as example (and synchronous dispatch queues, to get a
reliable answer), because its value is less „atomic“:
```swift
var shared_array = [Int]()
var not_shared_array = shared_array
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
var not_shared_array = shared_array
not_shared_array.append(1)
print("not shared 1: \(not_shared_array)")
shared_array.append(2)
print("shared 2: \(shared_array)")
}
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
var not_shared_array = shared_array
not_shared_array.append(3)
print("not shared 3: \(not_shared_array)")
shared_array.append(4)
print("shared 4: \(shared_array)")
}
not_shared_array.append(5)
shared_array.append(6)
print("not shared: \(not_shared_array)")
print("shared: \(shared_array)“)
// prints:
// not shared 1: [1]
// shared 2: [2]
// not shared 3: [2, 3]
// shared 4: [2, 4]
// not shared: [5]
// shared: [2, 4, 6]
```
You could do this without closures using a reference type as a wrapper, but you
still do not share the value instance but the wrapper:
```swift
class Wrapper {
var shared_array = [Int]()
}
func appendNumber(w: Wrapper, n: Int) {
w.shared_array.append(n)
}
func appendNumber(var v: [Int], n: Int) {
v.append(n)
}
let wi = Wrapper(),
vi = [Int]()
appendNumber(wi, n: 1)
appendNumber(vi, n: 2)
print(wi.shared_array)
print(vi)
// prints:
// [1]
// []
```
All the best
Johannes
>
> Johannes Neubauer <[email protected]> 於 2016年7月18日星期一 寫道:
>
> > Am 18.07.2016 um 06:47 schrieb Susan Cheng <[email protected]>:
> >
> > so, you want to propose default == operator but not forbidding all peoples
> > to custom == operator?
> > Why don't just adding the following function to std library?
> >
> > public func == <T : Equatable>(lhs: T, rhs: T) -> Bool {
> > var lhs = lhs
> > var rhs = rhs
> > return memcmp(&lhs, &rhs, sizeof(T.self)) == 0
> > }
>
> This does not work, because method parameters are statically dispatched. This
> function will never be executed for any type, that has a custom equality
> implementation. So this would not enforce this check upfront. You would need
> to copy this code to every custom implementation (which can be forgotten). Or
> you have to implement it like this
>
> ```swift
> public func isSame(lhs: Any, rhs: Any) -> Bool {
> // like above in your code
> }
>
> public func ==(lhs: MyType, rhs: MyType) -> Bool {
> if isSame(lhs, rhs: rhs) {
> return true
> }
> // do custom behavior
> }
> ```
>
> > Thread safety can't fixed by std library. Value type only can atomic
> > compared when additional mutex provided.
>
> Value types are either on the stack or they are **copied** to the heap (for
> protocol types with large value types). So, you don’t have any thread safety
> issues (as they are copied before they are changed in the new thread) as long
> as you don’t do (or check) anything on a property of a reference type,
> because the latter has shared **state**.
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution