繁体   English   中英

快速通用类型推断

[英]Swift Generic Type Inference

所以我想知道是否有人可以解释此错误背后的原因或对我正在做错的事情的解释。

我正在尝试创建一个通用的函数,该函数采用协议约束类型,该协议上有一个称为Solve的静态方法。

但是由于某种原因,即使它解决了Xcode中的约束问题,编译器仍会发出嘶嘶声。

是否有任何原因不能解释我已经指定的类型,或者我的代码示例中存在天真错误?

编辑:由于它不够明确

我知道如何解决它,我只是想解释一下为什么接口/协议中的静态成员有问题。

在此处输入图片说明

protocol NodeSolver {
    static func solve(_ nodes: [Node]) -> [Node]
}

func findPath<T: NodeSolver>(nodes: [Node]) -> [Node]  {        
        return T.solve(nodes)
    }

由于似乎您希望findPath是与符合NodeSolver类型紧密连接的方法,但不会在findPath方法本身中使用此具体NodeSolver类型的任何实例,因此您可能需要考虑简单地将常规findPath方法添加为类型默认实现的方法用于符合NodeSolver所有类型。

例如:

struct Node {}

protocol NodeSolver {
    static func solve(_ nodes: [Node]) -> [Node]
    static func findPath(nodes: [Node]) -> [Node]
}

extension NodeSolver {
    static func findPath(nodes: [Node]) -> [Node]  {
        // hopefully some more logic ...
        return Self.solve(nodes)
    }
}

struct MyNodeSolver: NodeSolver {
    // dummy solver
    static func solve(_ nodes: [Node]) -> [Node] {
        return nodes
    }
}

let myNodes = [Node(), Node()]

// make use of the default implementation of `findPath` available
// to all types conforming to 'NodeSolver': this method itself
// make use of the concrete type-specific implementation of 'solve'
// in the types conforming to 'NodeSolver'.
let dummyPath = MyNodeSolver.findPath(nodes: myNodes)

我在我指定的协议中传递了一个约束类型。 和方法调用中的实际类型。

 findPath<NodeSolver1>(nodes) findPath<NodeSolver2>(nodes) 

另一种可能更接近您要实现的解决方法是,将泛型函数包装到泛型类型(例如struct )中,该泛型类型包含非泛型函数findPath和泛型的具体版本。 如果从拥有类型外部的视点查看包装的findPath ,则该函数与拥有类型的泛型类型持有者是通用的。

例如:

struct Node {}

protocol NodeSolver {
    static func solve(_ nodes: [Node]) -> [Node]
}

struct NodeSolverA: NodeSolver {
    static func solve(_ nodes: [Node]) -> [Node] {
        return nodes
    }
}

struct NodeSolverB: NodeSolver {
    static func solve(_ nodes: [Node]) -> [Node] {
        return nodes.reversed()
    }
}

// instead of a generic function, wrap a concrete function
// in a generic type
struct AnyNodeSolver<T: NodeSolver> {
    static func findPath(nodes: [Node]) -> [Node]  {
        return T.solve(nodes)
    }
}

let myNodes = [Node(), Node()]

let dummyPathA = AnyNodeSolver<NodeSolverA>.findPath(nodes: myNodes)
let dummyPathB = AnyNodeSolver<NodeSolverB>.findPath(nodes: myNodes)

您必须在函数签名中指定T的类型。

func findPath<T: NodeSolver>(nodes: [Node], ofType type: T.Type) -> [Node]  {        
    return T.solve(nodes)
}

如果定义通用类型,则必须使编译器能够以某种方式推断实际类型。 目前尚无办法实现这一目标。 您将如何使用不同的NodeSolver对该方法进行两次调用?

Yannick为指定类型写了一个答案-您问“那么泛型的意义是什么?如果必须两次指定它?” - 你不必。 一般示例:

protocol P {
    static func solve(argument : String)
}

class P1 : P {
    class func solve(argument : String) {
        print("first")
    }
}

class P2 : P {
    class func solve(argument : String) {
        print("second")
    }
}


func doSome(argument : String, a : P.Type) {
    a.solve(argument: argument)
}

doSome(argument: "", a: P1.self) // prints "first"
doSome(argument: "", a: P2.self) // prints "second"

在您的情况下:

func findPath(nodes: [Node], solver: NodeSolver.Type) -> [Node]  {        
    return solver.solve(nodes)
}

与与之回复此问题的同事进行了交谈(在C#中,但相关)

并从语言实现方面解释了这个问题的问题。

感谢您的所有答复和时间。

https://blogs.msdn.microsoft.com/ericlippert/2007/06/14/calling-static-methods-on-type-parameters-is-illegal-part-one/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM