所以我想知道是否有人可以解释这个错误背后的原因或我做错了什么的解释。
我正在尝试创建一个通用函数,该函数采用协议(protocol)约束类型,该类型具有名为 solve 的静态方法。
但出于某种原因,即使它在 Xcode 中很好地解析了约束,编译器也会发出嘶嘶声。
是否有任何原因它不应该能够推断出我已经指定的类型,或者我的代码示例中是否存在天真的错误?
编辑:因为它不够明确
我知道如何解决它,我只是想知道为什么接口(interface)/协议(protocol)中的静态成员有问题的解释。
protocol NodeSolver {
static func solve(_ nodes: [Node]) -> [Node]
}
func findPath<T: NodeSolver>(nodes: [Node]) -> [Node] {
return T.solve(nodes)
}
最佳答案
因为您似乎希望 findPath
成为与符合 NodeSolver
的 type 紧密相关的方法,但不会使用任何实例这个具体的 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/