Re: [swift-users] Swift 4 Strings and flatMap
Compare https://bugs.swift.org/browse/SR-1570 : Swift can infer the return type from single-statement closures, but not from multi-statement closures. Therefore in let result = strArr.flatMap { x in return x } the closure type is inferred as (String)-> String, and therefore the flatMap call matches exactly the func flatMap(_ transform: (Self.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence Sequence method, with Self.Element == String and SegmentOfResult == String, and flatMap returns [SegmentOfResult.Element] == [Character]. In let result = strArr.flatMap { x in print(x) return x } the closure return type is not inferred from the closure itself, because it is a multi-statement closure. Here the compiler (apparently) chooses the public func flatMap(_ transform: (Element) throws -> String?) rethrows -> [String] Array method, and promotes `String` to `String?`. You would get the same result with an explicit return type in the single-statement closure: let result = strArr.flatMap { x -> String? in return x } But why do you use flatMap at all? If the intention is to map [String] to [String] then map() would be the right method: let strArr = ["Hi", "hello"] let result: [String] = strArr.map { x in return x } print(result) // ["Hi", "hello"] Regards, Martin > On 21. Oct 2017, at 02:50, Santiago Gil via swift-users >wrote: > > Hi Swift users, > > I just ran into a bug after a Swift 4 migration where we expected [String] > and got [Character] from a flatMap since flatMap will flatten the String > since it's now a collection. While I understand why flatMap behaves this way > now that string are collections, in testing this I found some weird > behaviour... > > var strArr = ["Hi", "hello"] > > let result = strArr.flatMap { x in > > return x > > } > > > The type of results ends up being [Character] in the above case. However, > adding a print statement changes things. > > > var strArr = ["Hi", "hello"] > > let result = strArr.flatMap { x in > > print(x) > > return x > > } > > In this case, result is of type [String] > > This seems like a bug, or is this expected Swift behaviour? > > Thanks, > > Santiago > > ___ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
Re: [swift-users] Swift 4 Strings and flatMap
On 21.10.17 02:50, Santiago Gil via swift-users wrote: I just ran into a bug after a Swift 4 migration where we expected [String] and got [Character] from a flatMap since flatMap will flatten the String since it's now a collection. While I understand why flatMap behaves this way now that string are collections, in testing this I found some weird behaviour... var strArr = ["Hi", "hello"] let result = strArr.flatMap { x in returnx } The type of results ends up being [Character] in the above case. However, adding a print statement changes things. var strArr = ["Hi", "hello"] let result = strArr.flatMap { x in print(x) return x } In this case, result is of type [String] This seems like a bug, or is this expected Swift behaviour? It looks like the compiler infers the type of the closure in the second example to be (String) -> Optional instead of String -> String. I don't know why and I definitely find it surprising. ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
Re: [swift-users] Re-initializing lazy vars
Oops! forgot to add example code for resetting with non-optional public var : public struct TestStruct { private var _description: String? public var description: String { get { return _description ?? "" } set { _description = newValue } } mutating func resetDescription() { _description = nil } } Joanna -- Joanna Carter Carter Consulting ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
Re: [swift-users] Re-initializing lazy vars
> It just seems so obvious to create-if-nil, and makes it nice to reset stuff > that should be re-created. In my case, after my NSURLSession gets > invalidated, I wanted to set the property to nil, and next time a session was > needed, it would just get created. The only thing I would query with the whole concept of resetting an implicitly unwrapped optional var is, with a simple example struct : public struct TestStruct { private var _description: String? public var description: String! { get { return _description ?? "" } set { _description = newValue } } } … test code would be : { var test = TestStruct() test.description = nil let str: String = test.description } The idea of setting a var to nil and then getting a valid object back seems a bit anachronistic. I think I would rather add an explicit "reset" method. Joanna -- Joanna Carter Carter Consulting ___ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users