Swift泛型函数、协议和关联类型-无法使用类型为';(from:T)和"x27,;

Swift泛型函数、协议和关联类型-无法使用类型为';(from:T)和"x27,;,swift,generics,protocols,keypaths,Swift,Generics,Protocols,Keypaths,我试图为不同类型的对象泛化一个函数,这些对象执行相同的操作(使用键路径从对象中检索值) class GenericOutputParameter:Equalable{ //交易参数的单行参数 变量路径:WritableKeyPathApplicator 变量标签:字符串 变量值:有吗?//这是可选的 var格式:Int var columnID:String 变量顺序:Int init(路径:WritableKeyPathApplicator,标签:String,值:Any?,格式:Int,顺序

我试图为不同类型的对象泛化一个函数,这些对象执行相同的操作(使用键路径从对象中检索值)

class GenericOutputParameter:Equalable{
//交易参数的单行参数
变量路径:WritableKeyPathApplicator
变量标签:字符串
变量值:有吗?//这是可选的
var格式:Int
var columnID:String
变量顺序:Int
init(路径:WritableKeyPathApplicator,标签:String,值:Any?,格式:Int,顺序:Int,columnID:String){
self.path=path
self.label=标签
自我价值=价值
self.format=格式
self.order=order
self.columnID=columnID
}
}
协议输出{
associatedtype容器类型
变量字典:[String:(路径:WritableKeyPathApplicator,标签:String,值:Any,格式:Int,顺序:Int)]{get set}
变量输出:[GenericOutputParameter]{get set}
}
func fillOutputs(容器:inout T){
container.outputs.removeAll()
对于container.dictionary中的(columnID,valueTuple){
container.outputs.append(GenericOutputParameter(路径:valueTuple.path,标签:valueTuple.label,值:valueTuple.path.retrieve(从:容器),格式:valueTuple.format,顺序:valueTuple.order,columnID:columnID))
}
container.outputs.sort(按:{$0.order<$1.order})
}//输出结束
我在协议中使用associatedType,因为每个对象都有自己不同的字典

函数fillOutputs(container:inout T)从对象中检索键路径指定的参数的值,并将其附加到数组中

代码末尾的container.outputs.append行中出现错误,如下所示:无法使用类型为“(from:T)”的参数列表调用“retrieve”。这是指检索(从:容器)。在尝试泛化之前,该函数是每个对象(容器)的一种方法,并使用retrieve(from:self)工作

作为参考,检索方法是另一个通用函数的一部分:

class WritableKeyPathApplicator<Type> {

    private let applicator: (Type, Any) -> Type
    private let retriever: (Type) -> Any

    init<ValueType>(_ keyPath: WritableKeyPath<Type, ValueType>) {

        applicator = {

            ...

            }


        retriever = {
            ...

            }

        }


    func apply(value: Any, to: Type) -> Type {
        return applicator(to, value)
        }


    func retrieve(from: Type)   -> Any  {
        return retriever(from)
        }

}
类可写KeyPathApplicator{
专用let治疗头:(类型,任意)->类型
私人出租检索器:(类型)->任意
init(keyPath:writeablekeypath){
敷贴器={
...
}
寻回犬={
...
}
}
func apply(值:Any,to:Type)->Type{
返回治疗头(至,值)
}
func retrieve(from:Type)->Any{
返回检索器(来自)
}
}

鉴于我不是Swift专家,也不完全理解协议,我可能会在一杯水中迷失自我,我将感谢任何想法/帮助。谢谢

这感觉太复杂了,但我在制定目标时遇到了麻烦。依靠
任何
几乎肯定是错误的。将其与泛型和具有关联类型(PAT)的协议耦合在一起肯定是太多了。“使用keyPath从对象检索值”只是
对象[keyPath:keyPath]
,那么这到底是在做什么呢?调用代码是什么样子的?什么算法利用了这个协议?Rob-谢谢你花时间。它的核心是一个表示对象数组的表。对象的属性位于表的列中。对象有许多不同类型的属性(大约100个)(字符串、Int、Double等)。每个属性都有一个不同的关联列名,并以不同的格式和颜色表示。该对象引用了一个字典,该字典存储GenericOutputParameter使用的属性。到目前为止,它很简单。但是有更多的表,用不同的参数表示属于不同类的不同对象。因此,无论属性属于哪个类,都需要以相同的方式处理每个属性表示的泛型函数。关键路径指向不同类型对象的不同参数。我希望这能澄清您的问题。您是否为一个(较小的)表编写了工作系统?从这里开始,包括(最重要的!)调用代码。什么东西会用这个?什么样的算法可以在这个数据结构上工作?(事实上,您返回的任何内容都意味着您几乎肯定已经破坏了您的调用代码。)然后构建第二个表。从那里,提炼出共同点。几乎可以肯定的是,这里需要一个简单的(非关联类型)协议来放入数组中。然后,您可能会添加一些其他协议(带有关联类型)来帮助共享代码。但这里最重要的是,您必须摆脱
任何
。这破坏了整个系统,我认为你无法解决它。同样,从调用代码开始工作,并确保您不需要像?
那样使用
,这将推动您朝着正确的方向前进。如果您给出一个示例,说明如何调用此代码并使用结果(不包括
as?
),那么我可能可以帮助您设计正确的数据结构来实现这一点。例如,这是否与tableview关联?
class WritableKeyPathApplicator<Type> {

    private let applicator: (Type, Any) -> Type
    private let retriever: (Type) -> Any

    init<ValueType>(_ keyPath: WritableKeyPath<Type, ValueType>) {

        applicator = {

            ...

            }


        retriever = {
            ...

            }

        }


    func apply(value: Any, to: Type) -> Type {
        return applicator(to, value)
        }


    func retrieve(from: Type)   -> Any  {
        return retriever(from)
        }

}