Swift 泛型类型推断

标签 swift generics types protocols inference

所以我想知道是否有人可以解释这个错误背后的原因或我做错了什么的解释。

我正在尝试创建一个通用函数,该函数采用协议(protocol)约束类型,该类型具有名为 solve 的静态方法。

但出于某种原因,即使它在 Xcode 中很好地解析了约束,编译器也会发出嘶嘶声。

是否有任何原因它不应该能够推断出我已经指定的类型,或者我的代码示例中是否存在天真的错误?

编辑:因为它不够明确

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

enter image description here

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

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

最佳答案

因为您似乎希望 findPath 成为与符合 NodeSolvertype 紧密相关的方法,但不会使用任何实例这个具体的 NodeSolver 类型在 findPath 方法本身中,您可能想考虑简单地添加通用的 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)

I am handing a constrained type in the protocol I am specifying. And the actual type in the method call.

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

另一种解决方法,可能更接近您要实现的目标,是将泛型函数包装到泛型类型(例如,struct)中,它包含一个非泛型函数 findPath w.r.t.通用类型的具体版本。如果从拥有类型外部的角度查看包装的 findPath,则函数是通用的 w.r.t.拥有类型的通用类型持有者。

例如:

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)

关于Swift 泛型类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42456514/

相关文章:

typescript - 是否可以在没有 "is not assignable to parameter of type ' never'"错误的情况下使用具有不同联合类型的数组元素?

javascript - 分配 onreadystatechange 时类型不匹配错误是什么意思?

ios - 我如何将所有内容从一个 WKWebView 复制到一个新的 WKWebView

java - Generic <T extends Comparable<T>, V extends T> is V required

typescript - 泛型函数中的属性类型

c# - 使用 Entity Framework 的通用存储库,如何查询实现特定接口(interface)的实体?

java - 为 toArray 方法创建通用数组

swift - 扩展泛型 Array<T> 以采用协议(protocol)

ios - 如何从弹出 View 中关闭第二个 View Controller

Swift 可变集 : Duplicate element found