Словарь значений, соответствующих протоколу, неоднозначен? - PullRequest
0 голосов
/ 19 сентября 2018

Я пытаюсь создать протокол "преобразования", которому может соответствовать Словарь, если его значения реализуют указанный протокол.

import Foundation

protocol Fooable {
    var foo:String { get }
}

extension Double:Fooable {
    var foo:String { get { return "number" } }
}

extension Int:Fooable {
    var foo:String { get { return "count" } }
}

extension String:Fooable {
    var foo:String { get { return "name" } }
}

extension Dictionary:Fooable where Key == String, Value:Fooable {
    var foo:String {
        get {
            var result = "["
            self.keys.sorted().forEach { key in
                result += key
                result += ": "
                result += self[key]!.foo
            }
            result += "]"
            return result
        }
    }
}

["a": 6.28, "b": 42, "c": "boo"].foo

Проблема в том, что последняя строка считается неоднозначной:

error: type of expression is ambiguous without more context
["a": 6.28, "b": 42, "c": "boo"].foo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~

То, что я пытаюсь сделать, даже выполнимо?Что мне нужно изменить или добавить, чтобы это работало?

ОБНОВЛЕНИЕ

Тип Erasure кажется одним из "решений".В общем, мне нужно сделать что-то вроде:

struct AnyFoo<Fooable> { }

Теперь я могу обернуть / стереть все в моем словаре:

["a": AnyFoo(6.28), "b": AnyFoo(42), "c": AnyFoo("boo")].foo

вместе с уточнением расширениясловаря для словаря, где значение равно AnyFoo.Действительно ли это лучше, чем просто ограничить расширение словаря для случаев, когда вместо него используется значение «Строка», и просто выполнить:

["a": 6.28.foo, "b": 42.foo, "c": "boo".foo].foo

Для простого случая «преобразования» я не уверен, что получу выгоду от использованияTypeErasure, чтобы отложить преобразование через оболочку, по сравнению с простым преобразованием перед созданием словаря.Менее фактический набор (как при вводе символов), чтобы сделать последнее.Так что я ничего не получил.

Если я что-то не упустил, для моего случая я, вероятно, просто пойду с понижением (например, as? Fooable) для элементов контейнера и сделаю что-то вроде logошибки или что-то.

...