In Swift, how to extend a typealias?

て烟熏妆下的殇ゞ 提交于 2019-11-30 23:46:37

问题


I have a typealias:

typealias BeaconId = [String: NSObject]

I'd like to extend it by doing something like:

extension BeaconId {}

But this throws a compile error:

Constrained extension must be declared on the unspecialized generic type 'Dictionary' with constraints specified by a 'where' clause

So I end up doing:

extension Dictionary where Key: StringLiteralConvertible, Value: NSObject {}

Is there a cleaner way to do this?


回答1:


AFAIK, no.

Consider the following example:

typealias Height: Float

extension: Height {

}

Here Height is not a new type, it's just a label for Float so you're just extending Float. If you take a look at Dictionary it's public struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible so what you'd be trying to achieve with

extension BeaconID {}

is adding an extension to Dictionary with specific generic parameters.

What I would expect that you should be able to do is:

typealias BeaconID = Dictionary<Key: String, Value: NSObject>

but that also doesn't compile and that's because in Swift you can't typealias partial types (in other words generic types without specific generic parameter types. See here for more info). A possible workaround for typealiasing generic types which is noted below the answer I linked to is

struct Wrapper<Key: Hashable, Value> {
    typealias T = Dictionary<Key, Value>
}
typealias BeaconID = Wrapper<String, NSObject>.T

but even then when you try to extend BeaconID, you get a compiler warning, which finally gets to the heart of the problem:

"Constrained extension must be declared on the unspecialized generic type 'Dictionary' with constraints specified by a 'where' clause"




回答2:


Update at the time of Swift 4.2: you can now do this

Example:

typealias KeyedNumbers = [String: Int]

extension KeyedNumbers {
    func squaredValue(forKey key: String) -> Int {
        return self[key]! * self[key]!
    }
}

With that (pretty useless) extension in place, you can do this:

let pairs = ["two": 2, "three": 3]
print("2 squared =", pairs.squaredValue(forKey: "two"))

And it will print

2 squared = 4



来源:https://stackoverflow.com/questions/33771368/in-swift-how-to-extend-a-typealias

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!