[swift-users] Which is the more idiomatic approach for pinning down the type of a generic parameter?

Marco Masser lists at duckcode.com
Wed Jan 20 05:25:32 CST 2016


> On 2016-01-20, at 11:25, zhaoxin肇鑫 <owenzx at gmail.com> wrote:
> 
> What about dropping T, just using Element, and converting Element to the type in your predicate?

As I wrote in my original message, I’m writing a whole set of findFirst() methods and one of them simply takes a predicate and returns an Element:

@warn_unused_result
func findFirst(@noescape predicate: Self.Generator.Element throws -> Bool) rethrows -> Self.Generator.Element? {
    for element in self where try predicate(element) {
        return element
    }
    return nil
}

If I understand correctly, you propose to check the type of the passed-in Element in the predicate, like this:

let result1 = containerView.subviews.findFirst { ($0 as? NSButton)?.state == NSOnState }

But that is cumbersome and has a very significant drawback: The type of result1 is now NSView, not NSButton.
That’s the whole point for the generic version of the method in my original message: the predicate doesn’t have to check the type, and the result of findFirst() has the type the caller specifies.
So to get the same result as with my generic method (but uglier and slower due to more type casts) you’d have to do this:

let result2 = containerView.subviews.findFirst { ($0 as? NSButton)?.state == NSOnState } as? NSButton

I think that’s not very nice compared to how the two generic versions in question look:

let result3 = containerView.subviews.findFirst(NSButton.self, matching: { $0.state == NSOnState })
or:
let result4: NSButton? = containerView.subviews.findFirst { $0.state == NSOnState }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160120/43a0f0c1/attachment.html>


More information about the swift-users mailing list