I know and I want to point out that you said value type don't have any thread safety issues is wrong.
Johannes Neubauer <neuba...@kingsware.de> 於 2016年7月20日星期三 寫道: > Dear Susan, > > > Am 20.07.2016 um 14:14 schrieb Susan Cheng <susan.dog...@gmail.com > <javascript:;>>: > > > > 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 <neuba...@kingsware.de <javascript:;>> 於 > 2016年7月18日星期一 寫道: > > > > > Am 18.07.2016 um 06:47 schrieb Susan Cheng <susan.dog...@gmail.com > <javascript:;>>: > > > > > > 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 swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution