How to make generics in collection type constraint?

后端 未结 3 981
执笔经年
执笔经年 2020-12-04 03:04

I have been trying to extract non-nil values from the String array. Like below. But, my senior wants it to be able to extract non-nil values from other type

3条回答
  •  难免孤独
    2020-12-04 03:31

    There's no easy way of achieving this through an extension, as you cannot introduce new generic types into extensions (although this is part of the Swift Generics Manifesto – so may well be possibly in a future version of Swift).

    As @kennytm says, the simplest solution is just to use flatMap, which filters out nil:

    x.flatMap{$0}.forEach { (str) in
        print(str)
    }
    

    If however, you still want this as an extension, you could use a protocol workaround in order to allow you to constrain the extension to any optional element type (Swift 3):

    protocol _OptionalProtocol {
        associatedtype Wrapped
        func _asOptional() -> Wrapped?
    }
    
    extension Optional : _OptionalProtocol {
        func _asOptional() -> Wrapped? {return self}
    }
    
    extension Collection where Self.Iterator.Element : _OptionalProtocol {
        func getNonNil() -> [Iterator.Element.Wrapped] {
            return flatMap{$0._asOptional()}
        }
    } 
    
    ...
    
    let x : [String?] = ["Er", "Err", nil, "errr"]
    
    x.getNonNil().forEach { (str) in
        print(str)
    }
    

    (In Swift 3, CollectionType has been renamed to Collection, and Generator is now Iterator)

    Although flatMap is almost certainly preferred in this situation, I'm only really adding this for the sake of completion.

提交回复
热议问题